diff --git a/Server/src/plugin/activity/pyramidplunder/PyramidPlunderMummyNPC.java b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderMummyNPC.java new file mode 100644 index 000000000..366453c46 --- /dev/null +++ b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderMummyNPC.java @@ -0,0 +1,53 @@ +package plugin.activity.pyramidplunder; +import org.crandor.game.node.entity.Entity; +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.world.map.Location; +import org.crandor.tools.RandomFunction; + +/** + * Handles the mummy NPC in pyramid plunder + * @author ceik + */ +public final class PyramidPlunderMummyNPC extends PyramidPlunderNPC { + + /** + * The swarm id. + */ + private static final int[] IDS = new int[] { 1958 }; + + public PyramidPlunderMummyNPC(int id, Location location, Player player) { + super(id, location, player); + } + + @Override + public void init() { + super.init(); + setRespawn(false); + getProperties().getCombatPulse().attack(player); + sendChat("How dare you disturb my rest!"); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + if (getProperties().getCombatPulse().isAttacking()) { + if (RandomFunction.random(40) < 2) { + sendChat("Leave this place!"); + } + } + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return victim == player; + } + + @Override + public int[] getIds() { + return IDS; + } + +} diff --git a/Server/src/plugin/activity/pyramidplunder/PyramidPlunderNPC.java b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderNPC.java new file mode 100644 index 000000000..b6dddafe8 --- /dev/null +++ b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderNPC.java @@ -0,0 +1,188 @@ +package plugin.activity.pyramidplunder; + +import org.crandor.game.interaction.MovementPulse; +import org.crandor.game.node.entity.Entity; +import org.crandor.game.node.entity.combat.CombatStyle; +import org.crandor.game.node.entity.npc.AbstractNPC; +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.world.GameWorld; +import org.crandor.game.world.map.Location; +import org.crandor.game.world.map.RegionManager; +import org.crandor.game.world.map.path.Pathfinder; +import org.crandor.plugin.Plugin; + +/** + * Handles a Pyramid Plunder enemy, adapted from AntiMacroNPC.java by ceikry + * @author Vexia + */ +public abstract class PyramidPlunderNPC extends AbstractNPC { + + /** + * The player. + */ + protected final Player player; + + /** + * The quotes the npc will say(null if none) + */ + private String[] quotes; + + /** + * The counter representing speech cycles. + */ + private int count; + + /** + * The time until the next speech. + */ + private int nextSpeech; + + /** + * If the players time is up. + */ + protected boolean timeUp; + + /** + * The end time. + */ + private int endTime; + + /** + * Constructs a new {@code AntiMacroNPC} {@code Object}. + * @param id the id. + * @param location the location. + * @param player the player. + */ + public PyramidPlunderNPC(int id, Location location, Player player) { + super(id, location); + this.player = player; + this.quotes = quotes; + this.endTime = (int) (GameWorld.getTicks() + (1000 / 0.6)); + } + + @Override + public void init() { + location = RegionManager.getSpawnLocation(player, this); + if (location == null) { + clear(); + return; + } + super.init(); + startFollowing(); + } + + @Override + public void handleTickActions() { + if (GameWorld.getTicks() > endTime) { + clear(); + } + if (!getLocks().isMovementLocked()) { + if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) { + dialoguePlayer = null; + } + } + if (!player.isActive() || !getLocation().withinDistance(player.getLocation(), 10)) { + handlePlayerLeave(); + } + if (!getPulseManager().hasPulseRunning()) { + startFollowing(); + } + if (quotes != null) { + if (nextSpeech < GameWorld.getTicks() && this.getDialoguePlayer() == null && !this.getLocks().isMovementLocked()) { + if (count > quotes.length - 1) { + return; + } + nextSpeech = (int) (GameWorld.getTicks() + (20 / 0.5)); + if (++count >= quotes.length) { + setTimeUp(true); + handleTimeUp(); + return; + } + } + } + } + + /** + * Called when the player is gone. + */ + public void handlePlayerLeave() { + clear(); + } + + /** + * Called when the quotes are finished. + */ + public void handleTimeUp() { + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style) { + if (entity instanceof Player && entity != player) { + ((Player) entity).getPacketDispatch().sendMessage("It's not after you."); + return false; + } + return super.isAttackable(entity, style); + } + + @Override + public void onRegionInactivity() { + super.onRegionInactivity(); + clear(); + } + + @Override + public void clear() { + super.clear(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return null; + } + + + + /** + * Starts following the player. + */ + public void startFollowing() { + getPulseManager().run(new MovementPulse(this, player, Pathfinder.DUMB) { + @Override + public boolean pulse() { + return false; + } + }, "movement"); + face(player); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + + /** + * Gets the timeUp. + * @return The timeUp. + */ + public boolean isTimeUp() { + return timeUp; + } + + /** + * Sets the timeUp. + * @param timeUp The timeUp to set. + */ + public void setTimeUp(boolean timeUp) { + this.timeUp = timeUp; + } + +} diff --git a/Server/src/plugin/activity/pyramidplunder/PyramidPlunderOptions.java b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderOptions.java index ad6986ba3..a0fd44473 100644 --- a/Server/src/plugin/activity/pyramidplunder/PyramidPlunderOptions.java +++ b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderOptions.java @@ -5,18 +5,16 @@ import org.crandor.game.content.global.action.ClimbActionHandler; import org.crandor.game.content.skill.Skills; import org.crandor.game.interaction.OptionHandler; import org.crandor.game.node.Node; -import org.crandor.game.node.entity.Entity; import org.crandor.game.node.entity.combat.ImpactHandler; import org.crandor.game.node.entity.npc.NPC; import org.crandor.game.node.entity.player.Player; import org.crandor.game.node.item.Item; import org.crandor.game.node.object.GameObject; -import org.crandor.game.world.map.Direction; +import org.crandor.game.world.GameWorld; import org.crandor.game.world.map.Location; import org.crandor.game.world.update.flag.context.Animation; import org.crandor.plugin.InitializablePlugin; import org.crandor.plugin.Plugin; -import org.crandor.plugin.PluginManager; import org.crandor.tools.RandomFunction; import java.util.Random; @@ -43,8 +41,14 @@ public final class PyramidPlunderOptions extends OptionHandler { return this; } public void rollSceptre(Player player){ - if(RandomFunction.random(1000) == 4){ - player.getInventory().add(new Item(9050)); + if(RandomFunction.random(1000) == 451){ + if(!player.getInventory().isFull()) { + player.getInventory().add(new Item(9044)); + player.getPacketDispatch().sendMessage("You find a strange object."); + } else { + player.getBank().add(new Item(9044)); + player.getPacketDispatch().sendMessage("You sense that something has appeared in your bank."); + } } } public final boolean success(final Player player, final int skill) { @@ -59,6 +63,7 @@ public final class PyramidPlunderOptions extends OptionHandler { } @Override public boolean handle(Player player, Node node, String option) { + int NPCDeathTime = GameWorld.getTicks() + (1000 / 6); Location room_entrance[] = {new Location(1927,4477), new Location(1927,4453), new Location(1943,4421), new Location(1954,4477), new Location(1974,4420), new Location(1977,4471), new Location(1927, 4424)}; int currentX = player.getLocation().getX(); int currentY = player.getLocation().getY(); @@ -151,6 +156,7 @@ public final class PyramidPlunderOptions extends OptionHandler { break; case 16473: if(option.equals("search") || option.equals("Search")) { + boolean willSpawnSwarm = (RandomFunction.random(1,20) == 10); if (reqLevel > level){ player.getPacketDispatch().sendMessage("You need to be at least level " + reqLevel + " thieving."); break; @@ -158,10 +164,18 @@ public final class PyramidPlunderOptions extends OptionHandler { player.getPacketDispatch().sendMessage("You search the chest..."); player.animate(animations[1]); player.lock(2); - player.getInventory().add(ARTIFACTS[RandomFunction.random(1,3)][RandomFunction.random(3)]); - rollSceptre(player); - player.getPacketDispatch().sendMessage("And you find an artifact!"); - player.getSkills().addExperience(Skills.THIEVING,40 + (room * 20)); + if(willSpawnSwarm) { + player.getPacketDispatch().sendMessage("A swarm flies out!"); + PyramidPlunderSwarmNPC swarm = new PyramidPlunderSwarmNPC(2001,player.getLocation(),player); + swarm.setRespawn(false); + swarm.setAggressive(true); + swarm.init(); + } else { + player.getInventory().add(ARTIFACTS[RandomFunction.random(1, 3)][RandomFunction.random(3)]); + rollSceptre(player); + player.getPacketDispatch().sendMessage("And you find an artifact!"); + player.getSkills().addExperience(Skills.THIEVING, 40 + (room * 20)); + } } break; case 16495: @@ -175,7 +189,7 @@ public final class PyramidPlunderOptions extends OptionHandler { player.getPacketDispatch().sendMessage("You open the sarcophagus and...."); if(willSpawnMummy) { player.getPacketDispatch().sendMessage("A mummy crawls out!"); - NPC mummy = NPC.create(1958, player.getLocation()); + PyramidPlunderMummyNPC mummy = new PyramidPlunderMummyNPC(1958, player.getLocation(),player); mummy.setRespawn(false); mummy.setAggressive(true); mummy.init(); @@ -199,6 +213,7 @@ public final class PyramidPlunderOptions extends OptionHandler { if (doesOpen) { player.getPacketDispatch().sendMessage("The door opens!"); player.getProperties().setTeleportLocation(room_entrance[room]); + player.getPacketDispatch().sendMessage("Room: " + (room + 1) + " Level required: " + (reqLevel + 10)); } else { player.getPacketDispatch().sendMessage("You fail to unlock the door."); } diff --git a/Server/src/plugin/activity/pyramidplunder/PyramidPlunderSwarmNPC.java b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderSwarmNPC.java new file mode 100644 index 000000000..97e267d40 --- /dev/null +++ b/Server/src/plugin/activity/pyramidplunder/PyramidPlunderSwarmNPC.java @@ -0,0 +1,53 @@ +package plugin.activity.pyramidplunder; +import org.crandor.game.node.entity.Entity; +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.world.map.Location; +import org.crandor.tools.RandomFunction; + +/** + * Handles the swarm NPC in pyramid plunder + * @author ceik + */ +public final class PyramidPlunderSwarmNPC extends PyramidPlunderNPC { + + /** + * The swarm id. + */ + private static final int[] IDS = new int[] { 2001 }; + + public PyramidPlunderSwarmNPC(int id, Location location, Player player) { + super(id, location, player); + } + + @Override + public void init() { + super.init(); + setRespawn(false); + getProperties().getCombatPulse().attack(player); + sendChat("bzzzzz"); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + if (getProperties().getCombatPulse().isAttacking()) { + if (RandomFunction.random(40) < 2) { + sendChat("bzzzzz"); + } + } + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return victim == player; + } + + @Override + public int[] getIds() { + return IDS; + } + +}