557 lines
14 KiB
Java
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;
|
|
}
|
|
|
|
}
|
|
|
|
}
|