Files
2009scape/Server/src/main/content/minigame/mta/impl/TelekineticZone.java
T
2024-06-08 11:55:23 +00:00

557 lines
14 KiB
Java

package content.minigame.mta.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import core.game.dialogue.DialogueAction;
import core.game.node.entity.skill.Skills;
import core.game.interaction.Option;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.GroundItem;
import core.game.node.item.GroundItemManager;
import core.game.node.item.Item;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.build.DynamicRegion;
import core.game.world.map.path.Path;
import core.game.world.map.path.Pathfinder;
import core.net.packet.PacketRepository;
import core.net.packet.context.CameraContext;
import core.net.packet.context.CameraContext.CameraType;
import core.net.packet.out.CameraViewPacket;
import core.tools.RandomFunction;
import content.minigame.mta.MTAType;
import content.minigame.mta.MTAZone;
/**
* Handles the telekinetic zone.
* @author Vexia, Player Name
*/
public class TelekineticZone extends MTAZone {
/**
* The statue used in the game.
*/
public static final int STATUE = 6888;
/**
* The player.
*/
private final Player player;
/**
* The mazes to choose from.
*/
private final List<Maze> mazes = new ArrayList<>(20);
/**
* The dynamic region.
*/
private DynamicRegion region;
/**
* The location.
*/
private Location base;
/**
* The maze.
*/
private Maze maze;
/**
* The statue item.
*/
private GroundItem statue;
/**
* The npc guardian.
*/
private NPC guardian;
/**
* The solved mazes.
*/
private int solved;
/**
* Constructs a new {@code TelekineticZone} {@code Object}
* @param player the player.
*/
public TelekineticZone(Player player) {
super("Telekinetic Theatre", new Item[] {});
this.player = player;
if (player != null) {
mazes.addAll(Arrays.asList(Maze.values()));
this.solved = player.getSavedData().getActivityData().getSolvedMazes();
}
}
/**
* Constructs a new {@code TelekineticZone} {@code Object}
*/
public TelekineticZone() {
this(null);
}
/**
* Starts the telekinetic game for a player.
* @param player the player.
*/
public static void start(Player player) {
setZone(player);
}
@Override
public void update(Player player) {
player.getPacketDispatch().sendString("" + player.getSavedData().getActivityData().getPizazzPoints(getType().ordinal()), getType().getOverlay().getId(), 4);
player.getPacketDispatch().sendString("" + solved, 198, 7);
}
@Override
public boolean leave(Entity entity, boolean logout) {
if (entity instanceof Player) {
Player player = entity.asPlayer();
if (player == null || player != this.player) {
return super.leave(entity, logout);
}
if (statue != null) {
GroundItemManager.destroy(statue);
}
if (guardian != null) {
guardian.clear();
}
player.removeAttribute("camera");
}
return super.leave(entity, logout);
}
@Override
public boolean interact(Entity e, Node target, Option option) {
return super.interact(e, target, option);
}
@Override
public boolean parseCommand(Player player, String name, String[] arguments) {
switch (name) {
case "childs":
for (int i = 0; i < 8; i++) {
player.getPacketDispatch().sendString("child=" + i, 198, i);
}
break;
case "reset":
if (player.getAttribute("camera", false)) {
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20));
player.setAttribute("camera", false);
return true;
}
return true;
}
return false;
}
@Override
public void configure() {
setUid(getName().hashCode());
region = DynamicRegion.create(13463);
setBase(Location.create(region.getBorders().getSouthWestX(), region.getBorders().getSouthWestY(), 0));
registerRegion(region.getId());
}
/**
* Sets up the player in the maze.
*/
public void setUp() {
Maze maze = this.maze == null ? RandomFunction.getRandomElement(mazes.toArray(new Maze[] {})) : null;
while (maze == null) {
maze = RandomFunction.getRandomElement(mazes.toArray(new Maze[] {}));
if (maze == this.maze) {
maze = null;
}
}
mazes.remove(maze);
setMaze(maze);
setNodes();
player.teleport(base.transform(maze.getBase()));
}
/**
* Sets up the nodes.
*/
public void setNodes() {
if (statue != null) {
GroundItemManager.destroy(statue);
}
if (guardian != null) {
guardian.clear();
}
moveStatue(base.transform(maze.getStatueLocation()));
guardian = NPC.create(3098, base.transform(maze.getGuardianLocation()));
guardian.setWalks(true);
guardian.init();
}
/**
* Moves the statue.
* @param location the location.
*/
public void moveStatue(Location location) {
if (statue != null) {
GroundItemManager.destroy(statue);
}
GroundItemManager.create(statue = createGroundItem(location));
}
/**
* Creates the statue ground item.
* @param location the location.
* @return the item.
*/
public GroundItem createGroundItem(Location location) {
GroundItem item = new GroundItem(new Item(STATUE), location, player) {
@Override
public boolean isActive() {
return !isRemoved();
}
};
return item;
}
/**
* Sets the telekinetic zone.
* @param player the player.
* @return the zone.
*/
public static TelekineticZone setZone(Player player) {
TelekineticZone zone = new TelekineticZone(player);
zone.configure();
zone.setUp();
player.setAttribute("tele-zone", zone);
return zone;
}
/**
* Gets the zone.
* @param player the player.
* @return the zone.
*/
public static TelekineticZone getZone(Player player) {
TelekineticZone zone = player.getAttribute("tele-zone", null);
if (zone == null) {
zone = setZone(player);
}
return zone;
}
/**
* Called when the player wins.
*/
private void win() {
solved++;
GroundItemManager.destroy(statue);
int points = 2;
player.getDialogueInterpreter().sendDialogue("Congratulations! You have received two Telekinetic Pizazz Points!");
if (solved >= 5) {
mazes.addAll(Arrays.asList(Maze.values()));
solved = 0;
points += 8;
player.getSkills().addExperience(Skills.MAGIC, 1000, true);
player.getInventory().add(new Item(563, 10));
player.getSavedData().getActivityData().setSolvedMazes(0);
player.getDialogueInterpreter().addAction(new DialogueAction() {
@Override
public void handle(Player player, int buttonId) {
player.getDialogueInterpreter().sendDialogue("Congratulations on solving five mazes in a row, have 8 bonus points,", "10 law runes and extra magic XP!");
}
});
}
player.getSavedData().getActivityData().setSolvedMazes(solved);
incrementPoints(player, MTAType.TELEKINETIC.ordinal(), points);
TelekineticZone.this.update(player);
player.setAttribute("camera", false);
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20));
NPC mazeGuard = NPC.create(3102, base.transform(maze.getEndLocation()));
mazeGuard.init();
}
/**
* Moves the statue with a telekinetic teleport.
*/
public void moveStatue() {
final Direction dir = getDir();
if (dir == null) {
player.sendMessage("Invalid move!");
return;
}
player.lock();
GameWorld.getPulser().submit(new Pulse(1, player) {
boolean win = false;
@Override
public boolean pulse() {
if (win) {
win();
return true;
}
Location next = statue.getLocation().transform(dir, 1);
Path path = Pathfinder.find(statue.getLocation(), next);
boolean end = !path.isSuccessful() || path.isMoveNear() || path.getPoints().size() > 2;
if (end) {
return true;
}
if (next.equals(base.transform(maze.getEndLocation()))) {
win = true;
}
moveStatue(next);
return end;
}
@Override
public void stop() {
player.unlock();
super.stop();
}
});
}
/**
* Observes from above.
* @param player the player.
*/
public void observe(Player player) {
if (player.getAttribute("camera", false)) {
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20));
player.setAttribute("camera", false);
return;
}
player.sendMessage("Click observe on the guardian to reset your camera, or use the command ::reset !");
Location l = base.transform(maze.getCameraLocation());
int x = l.getX();
int y = l.getY();
int yInc = -10;
int xInc = 0;
int speed = 95;
int height = 798;
player.setAttribute("camera", true);
if (maze == Maze.FOURTH) {
x += 11;
y += 15;
height = 799;
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x + xInc, y + yInc, height, 1, speed));
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x - 55, y - 25, height, 1, speed));
return;
}
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x + xInc, y + yInc, height, 1, speed));
PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + xInc, y + yInc, height, 1, speed));
}
/**
* Resets the player.
* @param player the player.
*/
public void reset(Player player) {
moveStatue(base.transform(maze.getStatueLocation()));
}
/**
* Gets the direction to go.
* @return the direction.
*/
private Direction getDir() {
int myX = player.getLocation().getLocalX();
int myY = player.getLocation().getLocalY();
// anything >= 23 is north, anything <= is south, any x <= 10 is west,
// any x >= 21 is east
int[] data = maze.getData();
if (myY >= data[0]) {
return Direction.NORTH;
} else if (myY <= data[1]) {
return Direction.SOUTH;
} else if (myX <= data[2]) {
return Direction.WEST;
} else if (myX >= data[3]) {
return Direction.EAST;
}
return null;
}
/**
* Gets the base.
* @return the base
*/
public Location getBase() {
return base;
}
/**
* Sets the base.
* @param base the base to set.
*/
public void setBase(Location base) {
this.base = base;
}
/**
* Gets the player.
* @return the player
*/
public Player getPlayer() {
return player;
}
/**
* Gets the maze.
* @return the maze
*/
public Maze getMaze() {
return maze;
}
/**
* Sets the maze.
* @param maze the maze to set.
*/
public void setMaze(Maze maze) {
this.maze = maze;
}
/**
* Gets the solved.
* @return the solved
*/
public int getSolved() {
return solved;
}
/**
* Sets the solved.
* @param solved the solved to set.
*/
public void setSolved(int solved) {
this.solved = solved;
}
/**
* A maze.
* @author Vexia
*/
public enum Maze {
FIRST(new Location(8, 54, 0), new Location(15, 41, 0), new Location(8, 39, 0), new Location(19, 50, 0), new Location(15, 45, 0), new int[] { 51, 40, 9, 20 }), // http://puu.sh/cbh82/a0f9f3d206.png
SECOND(new Location(34, 49, 1), new Location(22, 53, 1), new Location(26, 48, 1), new Location(13, 44, 1), new Location(17, 48, 1), new int[] { 54, 43, 12, 23 }), // http://puu.sh/cbgzG/ab25358b4c.png
THIRD(new Location(54, 34, 1), new Location(48, 22, 1), new Location(45, 15, 1), new Location(57, 22, 1), new Location(53, 17, 1), new int[] { 23, 12, 47, 58 }), // http://puu.sh/cbgRX/d229c6129b.png
FOURTH(new Location(50, 42, 1), new Location(46, 49, 1), new Location(57, 41, 1), new Location(55, 49, 1), new Location(50, 53, 1), new int[] { 59, 48, 45, 56 }), // http://puu.sh/cbgMW/7bd91b0ed1.png
FITH(new Location(46, 32, 0), new Location(45, 14, 0), new Location(45, 23, 0), new Location(47, 18, 0), new Location(45, 13, 0), new int[] { 19, 8, 40, 51 }), // http://puu.sh/cbhuc/83da140de5.png
SIXTH(new Location(26, 26, 0), new Location(15, 16, 0), new Location(23, 24, 0), new Location(14, 20, 0), new Location(14, 15, 0), new int[] { 21, 10, 9, 10 }), // http://puu.sh/cbgHl/cb55b8011e.png
SEVENTH(new Location(51, 52, 0), new Location(40, 48, 0), new Location(55, 50, 0), new Location(39, 56, 0), new Location(43, 51, 0), new int[] { 57, 46, 37, 48 }), // http://puu.sh/cbgXl/73a9311a76.png
EIGTH(new Location(31, 37, 2), new Location(18, 54, 2), new Location(28, 41, 2), new Location(17, 54, 2), new Location(19, 49, 2), new int[] { 55, 44, 14, 25 }), // http://puu.sh/cbgAV/a2f71c6279.png
NINTH(new Location(40, 16, 2), new Location(20, 10, 2), new Location(34, 15, 2), new Location(11, 19, 2), new Location(16, 14, 2), new int[] { 20, 9, 10, 21 }), // http://puu.sh/cbhbR/59a1477b0c.png
TENTH(new Location(27, 29, 1), new Location(23, 20, 1), new Location(31, 25, 1), new Location(25, 16, 1), new Location(23, 20, 1), new int[] { 26, 15, 17, 28 });// http://puu.sh/cbh58/1cd226cbc0.png
/**
* The location base of where to start.
*/
private final Location base;
/**
* The start location of the statue.
*/
private final Location statueLocation;
/**
* The guardian location.
*/
private final Location guardianLocation;
/**
* The ending location.
*/
private final Location endLocation;
/**
* The location camera.
*/
private final Location cameraLocation;
/**
* The data used to create movements.
*/
private final int[] data;
/**
* Constructs a new {@code Maze} {@code Object}
* @param base the base.
* @param statueLocation the statue location.
* @param guardianLocation the guardian location.
* @param endLocation the end location.
* @param cameraLocation the camera location.
*/
private Maze(Location base, Location statueLocation, Location guardianLocation, Location endLocation, Location cameraLocation, int[] data) {
this.base = base;
this.statueLocation = statueLocation;
this.guardianLocation = guardianLocation;
this.endLocation = endLocation;
this.cameraLocation = cameraLocation;
this.data = data;
}
/**
* Gets the base.
* @return the base
*/
public Location getBase() {
return base;
}
/**
* Gets the statueLocation.
* @return the statueLocation
*/
public Location getStatueLocation() {
return statueLocation;
}
/**
* Gets the guardianLocation.
* @return the guardianLocation
*/
public Location getGuardianLocation() {
return guardianLocation;
}
/**
* Gets the endLocation.
* @return the endLocation
*/
public Location getEndLocation() {
return endLocation;
}
/**
* Gets the cameraLocation.
* @return the cameraLocation
*/
public Location getCameraLocation() {
return cameraLocation;
}
/**
* Gets the data.
* @return the data
*/
public int[] getData() {
return data;
}
}
}