RuneHive-Game
Loading...
Searching...
No Matches
PestControlGame.java
Go to the documentation of this file.
1package com.runehive.content.activity.impl.pestcontrol;
2
3import com.runehive.content.ActivityLog;
4import com.runehive.content.achievement.AchievementHandler;
5import com.runehive.content.achievement.AchievementKey;
6import com.runehive.content.activity.Activity;
7import com.runehive.content.activity.ActivityDeathType;
8import com.runehive.content.activity.ActivityType;
9import com.runehive.content.activity.lobby.LobbyManager;
10import com.runehive.content.activity.lobby.LobbyNode;
11import com.runehive.content.activity.panel.Activity_Panel;
12import com.runehive.content.event.impl.ObjectInteractionEvent;
13import com.runehive.game.Animation;
14import com.runehive.game.Graphic;
15import com.runehive.game.world.World;
16import com.runehive.game.world.entity.Entity;
17import com.runehive.game.world.entity.mob.Mob;
18import com.runehive.game.world.entity.mob.npc.Npc;
19import com.runehive.game.world.entity.mob.npc.NpcDeath;
20import com.runehive.game.world.entity.mob.player.Player;
21import com.runehive.game.world.entity.mob.player.PlayerRight;
22import com.runehive.game.world.items.Item;
23import com.runehive.game.world.pathfinding.TraversalMap;
24import com.runehive.game.world.position.Area;
25import com.runehive.game.world.position.Position;
26import com.runehive.net.packet.out.SendMessage;
27import com.runehive.util.RandomUtils;
28import com.runehive.util.Utility;
29
30import java.util.HashSet;
31import java.util.Optional;
32import java.util.Set;
33
34import static com.runehive.game.world.entity.combat.attack.listener.SimplifiedListener.CANT_ATTACK;
35
36public class PestControlGame extends LobbyNode {
37
38 /** The position of the pest control boat. */
39 private static final Position BOAT = new Position(2656, 2609);
40
41 /** The position outside the pest control boat. */
42 private static final Position OUTSIDE_BOAT_POSITION = new Position(2657, 2639);
43
44 /** The Pest control activity listener. */
46
47 /** The void knight. */
48 private final Npc voidKnight = new Npc(1756, Position.create(2656, 2592));
49
50 /** The portal names. */
51 private static final String[] PORTAL_NAMES = {
52 "Purple Portal",
53 "Blue Portal",
54 "Yellow Portal",
55 "Red Portal"
56 };
57
58 /** The portals. */
59 private final Portal[] portals = new Portal[] {
60 /* Purple */ new Portal(1739, Position.create(2628, 2591)),
61 /* Blue */ new Portal(1740, Position.create(2680, 2588)),
62 /* Yellow */ new Portal(1741, Position.create(2669, 2570)),
63 /* Red */ new Portal(1742, Position.create(2645, 2569))
64 };
65
66 private static final Position BLUE_BOUNDS = new Position(2679, 2587);
67 private static final Position RED_BOUNDS = new Position(2644, 2568);
68 private static final Position YELLOW_BOUNDS = new Position(2668, 2569);
69 private static final Position PURPLE_BOUNDS = new Position(2627, 2590);
70 private static final Position KNIGHT_BOUNDS = new Position(2654, 2590);
71
72 private static final int[] RAVAGERS = {1704, 1705, 1706, 1707, 1708};
73 private static final int[] SPLATTERS = {1691, 1692};
74 private static final int[] SHIFTERS = {1698, 1699, 1700, 1701};
75 private static final int[] DEFILERS = {1728, 1729};
76 private static final int[] TORCHERS = {1728, 1729};
77
78 /** The void knight messages that he will chant. */
79 private static final String[] VOID_KNIGHT_MESSAGES = {
80 "We must not fail!",
81 "Take down the portals",
82 "The Void Knights will not fall!",
83 "Hail the Void Knights!",
84 "We are beating these scum!"
85 };
86
87 /** The active monsters. */
88 private Set<Npc> monsters = new HashSet<>();
89
90 /** The active portals. */
91 private Set<Npc> portalSet = new HashSet<>();
92
97
98 @Override
99 public void sequence() {
100 super.sequence();
101
102 if (!inLobby()) {
103 if (getTicks() == 0) {
105 return;
106 }
107
108 if (getTicks() % 20 == 0) {
110
111 if (getTicks() > 10) {
113 }
114 }
115 }
116
117 forEachActivity((mob, activity) -> activity.getPanel().ifPresent(panel -> ((PestControlPanel) panel).update()));
118 }
119
120 @Override
121 protected void onStart() {
122 forEachActivity((mob, activity) -> {
123 if (mob.isPlayer()) {
124 mob.getPlayer().playerAssistant.restore();
125 }
126 });
127
129 voidKnight.blockFace = true;
130
131 for (Npc portal : portals) {
132 add(portal);
133 portalSet.add(portal);
134 }
135
136 groupMessage("Protect the void knight at all costs, good luck!");
138 }
139
140 @Override
141 public void onDeath(Mob mob) {
142 if (mob.isNpc()) {
143 Npc npc = mob.getNpc();
144
145 if (npc.id >= 1739 && npc.id <= 1742) {
146 portalSet.remove(npc);
147 voidKnight.heal(25);
148 groupMessage("The " + PORTAL_NAMES[npc.id - 1739] + " is dead! The Void Knight has gained 25 HP.");
149 } else {
150 monsters.remove(mob.getNpc());
151 }
152
153 World.schedule(new NpcDeath(mob.getNpc(), () -> remove(mob)));
154 } else {
155 mob.move(BOAT.transform(Utility.random(4), Utility.random(6)));
156 mob.getPlayer().animate(Animation.RESET, true);
157 mob.getPlayer().graphic(Graphic.RESET, true);
158 }
159 }
160
161 @Override
162 public void onLogout(Player player) {
163 removeActivity(player);
164 }
165
166 @Override
167 public boolean canLogout(Player player) {
168 player.message("You cannot log out during a Pest Control game.");
169 return false;
170 }
171
172 @Override
173 public void onRegionChange(Player player) {
174 if (!Area.inPestControl(player)) {
175 removeActivity(player);
176 }
177 }
178
179 @Override
180 protected boolean clickObject(Player player, ObjectInteractionEvent event) {
181 if (event.getObject().getId() == 14314) {
182 manager.leave(player);
183 return true;
184 }
185 return false;
186 }
187
188 @Override
189 public void finish() {
190 super.finish();
191 remove(voidKnight);
192 monsters.forEach(this::remove);
193 portalSet.forEach(this::remove);
194 monsters.clear();
195 portalSet.clear();
196 }
197
198 @Override
199 protected Optional<PestControlListener> getListener() {
200 return Optional.of(listener);
201 }
202
203 @Override
206 }
207
208 @Override
210 return ActivityDeathType.SAFE;
211 }
212 @Override
213 protected Activity createActivity(Player player) {
214 PestControlNode node = new PestControlNode(player);
215
216 PestControlPanel panel = new PestControlPanel(player, node);
217 panel.open();
218
219 return node;
220 }
221
222 @Override
223 protected boolean finished() {
224 if (getTicks() == FINISH || getActiveSize() == 0) {
225 return true;
226 }
227
228 if (!inLobby()) {
229 if (portalSet.isEmpty()) {
230 return true;
231 }
232
233 if (voidKnight.isRegistered() && voidKnight.getCurrentHealth() <= 0) {
234 return true;
235 }
236 }
237
238 return false;
239 }
240
241 private void spawnMonsters() {
242 for (int index = 0; index < 5; index++) {
244 }
245 for (int index = 0; index < 5; index++) {
247 }
248 for (int index = 0; index < 5; index++) {
250 }
251 for (int index = 0; index < 5; index++) {
253 }
254 for (int index = 0; index < 2; index++) {
256 }
257 }
258
259 private void spawn(int id, Position southWest, int size) {
260 Position target = RandomUtils.random(TraversalMap.getTraversableTiles(southWest, size, size));
261 Npc monster = new Npc(id, target);
262 monsters.add(monster);
263 add(monster);
264 }
265
266 private void agressiveMonsters() {
267 if (monsters.isEmpty())
268 return;
269 if (voidKnight == null)
270 return;
271 for (Npc monster : monsters) {
272 if (monster.getCombat().inCombat())
273 continue;
274 if (monster.getPosition().isWithinDistance(voidKnight.getPosition(), 10)) {
275 monster.getCombat().attack(voidKnight);
276 continue;
277 }
278 activities.keySet().forEach(mob -> {
279 if (!mob.isPlayer())
280 return;
281 if (monster.getPosition().isWithinDistance(mob.getPosition(), 8))
282 monster.getCombat().attack(mob);
283 });
284 }
285 }
286
287 private class Portal extends Npc {
289 super(id, position);
290 walk = false;
291 getCombat().addListener(CANT_ATTACK);
292 }
293 }
294
295 public class PestControlNode extends Activity {
296
297 /** The amount of damage the player has dealt. */
298 public int damage;
299 private final Player player;
300
302 super(1, Entity.DEFAULT_INSTANCE);
303 this.player = player;
304 }
305
306 @Override
307 protected void start() {
308 player.move(BOAT.transform(Utility.random(4), Utility.random(6)));
309 player.dialogueFactory.sendNpcChat(1756, "Go with strength!", "Defend the void knight and destroy the portals!", "You are our only hope!").execute();
310 }
311
312 @Override
313 public void finish() {
314 if (!inLobby() && !Area.inPestControl(player)) {
315 return;
316 }
317
318 getPanel().ifPresent(Activity_Panel::close);
320 player.playerAssistant.restore();
321 player.animate(Animation.RESET, true);
322 player.graphic(Graphic.RESET, true);
323
324 if (inLobby()) {
325 return;
326 }
327
328 if (voidKnight.getCurrentHealth() <= 0) {
329 player.dialogueFactory.sendNpcChat(1756, "You let the Void Knight die!", "Keep him alive you noobs...").execute();
330 return;
331 }
332
333 if (portalSet.isEmpty()) {
334 if (damage == 0) {
335 player.dialogueFactory.sendNpcChat(1756, "You have disgraced your squad by not dealing any damage.", "As punishment, you get no points! Teamwork next time!").execute();
336 return;
337 }
338
339 if (damage < 50) {
340 player.dialogueFactory.sendNpcChat(1756, "You only dealt " + damage + " damage this round.", "You need to deal at least 50 damage to receive a reward.").execute();
341 return;
342 }
343
344 int points = PlayerRight.getBloodMoney(player) / 100;
346 player.activityLogger.add(ActivityLog.PEST_CONTROL);
347 player.pestPoints += points;
348 player.dialogueFactory.sendNpcChat(1756, "You have beaten the minigame!", "You were rewarded with " + points + " pest control points.", "You now have: " + player.pestPoints + ".").execute();
349 } else {
350 player.dialogueFactory.sendNpcChat(1756, "You have run out of time!", "You failed the mission and don't get any points.").execute();
351 }
352 }
353
354 @Override
355 public void cleanup() {}
356
357 @Override
360 }
361
362 }
363 @Override
364 public boolean canTeleport(Player player) {
365 player.send(new SendMessage("Talk to the void-knight next to the boat to leave."));
366 return false;
367 }
368
369 private final class PestControlPanel extends Activity_Panel {
370 private final PestControlNode node;
371
373 super(player, "Pest Control");
374 this.node = node;
375 node.setPanel(this);
376 }
377
378 public void update() {
379 if (inLobby()) {
380 set(0, "Next Departure: <col=FF5500>" + Utility.getTime(getTicks()) + "</col>");
381 set(1, "Players Ready: <col=FF5500>" + getActiveSize() + "</col>");
382 set(2, "(Need <col=FF5500>" + manager.getMinimumRequired() + "</col> to " + manager.getPlayerCapacity() + " players)");
383 set(3, "Points: <col=FF5500>" + node.player.pestPoints + "</col>");
384 setFooter("Players Ready:");
385 setProgress((int) Utility.getPercentageAmount(getActiveSize(), manager.getPlayerCapacity()));
386 } else {
387 set(0, "Time remaining: <col=FF5500>" + Utility.getTime(getTicks()) + "</col>");
388 set(1, "Knight's health: <col=FF5500>" + voidKnight.getCurrentHealth() + "</col>");
389 set(2, "Damage: <col=FF5500>" + node.damage + "</col>");
390 int dead = 0;
391 for (int index = 0; index <= 3; index++) {
392 String value = "dead";
393 Portal portal = portals[index];
394 if (portal.getCurrentHealth() > 0) {
395 value = String.valueOf(portal.getCurrentHealth());
396 } else {
397 dead++;
398 }
399 set(3 + index, PORTAL_NAMES[index] + ": <col=FF5500>" + value + "</col>");
400 }
401 setFooter("Minigame Completion:");
403 }
404 setItem(new Item(11666));
405 }
406 }
407
408}
static void activate(Player player, AchievementKey achievement)
Activates the achievement for the individual player.
A Activity object constructs an in-game activity and sequences it through the start() and finish() me...
Definition Activity.java:31
Activity(int cooldown, int instance)
Constructs a new SequencedMinigame object.
Definition Activity.java:55
static final int FINISH
The 'finish' cooldown id.
Definition Activity.java:37
int getTicks()
Gets the current ticks.
void add(Mob mob)
Adds a mob to the activity.
final void finishCooldown()
Sets the cooldown flag to FINISH.
Activity_Panel panel
The panel for this activity.
Definition Activity.java:52
Optional< Activity_Panel > getPanel()
Gets an optional of the activity panel.
final void removeActivity(Mob mob)
Removes an activity from the activities group.
final void groupMessage(String message)
Sends a message to all the players in the group.
final Map< Mob, Activity > activities
A map of activities that handles each mob individually.
void forEachActivity(BiConsumer< Mob, Activity > activity)
Loops through all the activities.
int getActiveSize()
Gets the size of the activities in this group.
static final Position OUTSIDE_BOAT_POSITION
The position outside the pest control boat.
Optional< PestControlListener > getListener()
Gets an Optional of the ActivityListener for this activity.
static final Position BOAT
The position of the pest control boat.
static final String[] VOID_KNIGHT_MESSAGES
The void knight messages that he will chant.
boolean canTeleport(Player player)
Called when the player attempts to teleport.
final PestControlListener listener
The Pest control activity listener.
void onLogout(Player player)
Called when the player logs out.
boolean clickObject(Player player, ObjectInteractionEvent event)
void onRegionChange(Player player)
Called when the player changes region.
Class that models a single animation used by an entity.
static final Animation RESET
Represents a single graphic that can be used by entities.
Definition Graphic.java:10
static final Graphic RESET
Definition Graphic.java:17
Represents the game world.
Definition World.java:46
static void schedule(Task task)
Submits a new event.
Definition World.java:247
Represents a character in the game world, i.e.
Definition Entity.java:13
Handles the mob class.
Definition Mob.java:66
void move(Position position)
Moves the mob to a set position.
Definition Mob.java:340
final boolean isNpc()
Check if an entity is an npc.
Definition Mob.java:550
Optional< Graphic > graphic
Definition Mob.java:91
Represents a non-player character in the in-game world.
Definition Npc.java:29
Npc(int id, Position position)
Definition Npc.java:46
Combat< Npc > getCombat()
The combat of the mob.
Definition Npc.java:156
This class represents a character controlled by a player.
Definition Player.java:125
The container class that represents an item that can be interacted with.
Definition Item.java:21
Contains traversal data for a set of regions.
static List< Position > getTraversableTiles(Position southWest, int width, int length)
Returns a List of positions that are traversable from the specified position.
Handles checking if mobs are in a certain area.
Definition Area.java:13
static boolean inPestControl(Interactable entity)
Definition Area.java:329
Represents a single tile on the game world.
Definition Position.java:14
static Position create(int x, int y, int z)
Creates a location.
The OutgoingPacket that sends a message to a Players chatbox in the client.
A static-util class that provides additional functionality for generating pseudo-random numbers.
static< T > T random(T[] array)
Pseudo-randomly retrieves a element from array.
Handles miscellaneous methods.
Definition Utility.java:27
static int random(int bound)
Definition Utility.java:239
static double getPercentageAmount(int progress, int total)
Gets a percentage amount.
Definition Utility.java:36
static< T > T randomElement(Collection< T > collection)
Picks a random element out of any array type.
Definition Utility.java:248
static String getTime()
Gets the current server time and formats it.
Definition Utility.java:141
The activity log class.
Holds all activity types that are timed.