RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
PestControlGame.java
1package com.osroyale.content.activity.impl.pestcontrol;
2
3import com.osroyale.content.ActivityLog;
4import com.osroyale.content.achievement.AchievementHandler;
5import com.osroyale.content.achievement.AchievementKey;
6import com.osroyale.content.activity.Activity;
7import com.osroyale.content.activity.ActivityDeathType;
8import com.osroyale.content.activity.ActivityType;
9import com.osroyale.content.activity.lobby.LobbyManager;
10import com.osroyale.content.activity.lobby.LobbyNode;
11import com.osroyale.content.activity.panel.Activity_Panel;
12import com.osroyale.content.event.impl.ObjectInteractionEvent;
13import com.osroyale.game.Animation;
14import com.osroyale.game.Graphic;
15import com.osroyale.game.world.World;
16import com.osroyale.game.world.entity.Entity;
17import com.osroyale.game.world.entity.mob.Mob;
18import com.osroyale.game.world.entity.mob.npc.Npc;
19import com.osroyale.game.world.entity.mob.npc.NpcDeath;
20import com.osroyale.game.world.entity.mob.player.Player;
21import com.osroyale.game.world.entity.mob.player.PlayerRight;
22import com.osroyale.game.world.items.Item;
23import com.osroyale.game.world.pathfinding.TraversalMap;
24import com.osroyale.game.world.position.Area;
25import com.osroyale.game.world.position.Position;
26import com.osroyale.net.packet.out.SendMessage;
27import com.osroyale.util.RandomUtils;
28import com.osroyale.util.Utility;
29
30import java.util.HashSet;
31import java.util.Optional;
32import java.util.Set;
33
34import static com.osroyale.game.world.entity.combat.attack.listener.SimplifiedListener.CANT_ATTACK;
35
72
73public class PestControlGame extends LobbyNode {
74
76 private static final Position BOAT = new Position(2656, 2609);
77
79 private static final Position OUTSIDE_BOAT_POSITION = new Position(2657, 2639);
80
82 private final PestControlListener listener = new PestControlListener(this);
83
85 private final Npc voidKnight = new Npc(1756, Position.create(2656, 2592));
86
88 private static final String[] PORTAL_NAMES = {
89 "Purple Portal",
90 "Blue Portal",
91 "Yellow Portal",
92 "Red Portal"
93 };
94
96 private final Portal[] portals = new Portal[] {
97 /* Purple */ new Portal(1739, Position.create(2628, 2591)),
98 /* Blue */ new Portal(1740, Position.create(2680, 2588)),
99 /* Yellow */ new Portal(1741, Position.create(2669, 2570)),
100 /* Red */ new Portal(1742, Position.create(2645, 2569))
101 };
102
103 private static final Position BLUE_BOUNDS = new Position(2679, 2587);
104 private static final Position RED_BOUNDS = new Position(2644, 2568);
105 private static final Position YELLOW_BOUNDS = new Position(2668, 2569);
106 private static final Position PURPLE_BOUNDS = new Position(2627, 2590);
107 private static final Position KNIGHT_BOUNDS = new Position(2654, 2590);
108
109 private static final int[] RAVAGERS = {1704, 1705, 1706, 1707, 1708};
110 private static final int[] SPLATTERS = {1691, 1692};
111 private static final int[] SHIFTERS = {1698, 1699, 1700, 1701};
112 private static final int[] DEFILERS = {1728, 1729};
113 private static final int[] TORCHERS = {1728, 1729};
114
116 private static final String[] VOID_KNIGHT_MESSAGES = {
117 "We must not fail!",
118 "Take down the portals",
119 "The Void Knights will not fall!",
120 "Hail the Void Knights!",
121 "We are beating these scum!"
122 };
123
125 private Set<Npc> monsters = new HashSet<>();
126
128 private Set<Npc> portalSet = new HashSet<>();
129
130 PestControlGame(LobbyManager manager) {
131 super(manager);
132 setInstance(Entity.DEFAULT_INSTANCE);
133 }
134
135 @Override
136 public void sequence() {
137 super.sequence();
138
139 if (!inLobby()) {
140 if (getTicks() == 0) {
142 return;
143 }
144
145 if (getTicks() % 20 == 0) {
146 voidKnight.speak(Utility.randomElement(VOID_KNIGHT_MESSAGES));
147
148 if (getTicks() > 10) {
149 agressiveMonsters();
150 }
151 }
152 }
153
154 forEachActivity((mob, activity) -> activity.getPanel().ifPresent(panel -> ((PestControlPanel) panel).update()));
155 }
156
157 @Override
158 protected void onStart() {
159 forEachActivity((mob, activity) -> {
160 if (mob.isPlayer()) {
161 mob.getPlayer().playerAssistant.restore();
162 }
163 });
164
165 add(voidKnight);
166 voidKnight.blockFace = true;
167
168 for (Npc portal : portals) {
169 add(portal);
170 portalSet.add(portal);
171 }
172
173 groupMessage("Protect the void knight at all costs, good luck!");
174 spawnMonsters();
175 }
176
177 @Override
178 public void onDeath(Mob mob) {
179 if (mob.isNpc()) {
180 Npc npc = mob.getNpc();
181
182 if (npc.id >= 1739 && npc.id <= 1742) {
183 portalSet.remove(npc);
184 voidKnight.heal(25);
185 groupMessage("The " + PORTAL_NAMES[npc.id - 1739] + " is dead! The Void Knight has gained 25 HP.");
186 } else {
187 monsters.remove(mob.getNpc());
188 }
189
190 World.schedule(new NpcDeath(mob.getNpc(), () -> remove(mob)));
191 } else {
192 mob.move(BOAT.transform(Utility.random(4), Utility.random(6)));
193 mob.getPlayer().animate(Animation.RESET, true);
194 mob.getPlayer().graphic(Graphic.RESET, true);
195 }
196 }
197
198 @Override
199 public void onLogout(Player player) {
200 removeActivity(player);
201 }
202
203 @Override
204 public boolean canLogout(Player player) {
205 player.message("You cannot log out during a Pest Control game.");
206 return false;
207 }
208
209 @Override
210 public void onRegionChange(Player player) {
211 if (!Area.inPestControl(player)) {
212 removeActivity(player);
213 }
214 }
215
216 @Override
217 protected boolean clickObject(Player player, ObjectInteractionEvent event) {
218 if (event.getObject().getId() == 14314) {
219 manager.leave(player);
220 return true;
221 }
222 return false;
223 }
224
225 @Override
226 public void finish() {
227 super.finish();
228 remove(voidKnight);
229 monsters.forEach(this::remove);
230 portalSet.forEach(this::remove);
231 monsters.clear();
232 portalSet.clear();
233 }
234
235 @Override
236 protected Optional<PestControlListener> getListener() {
237 return Optional.of(listener);
238 }
239
240 @Override
241 public ActivityType getType() {
242 return ActivityType.PEST_CONTROL;
243 }
244
245 @Override
246 public ActivityDeathType deathType() {
247 return ActivityDeathType.SAFE;
248 }
249 @Override
250 protected Activity createActivity(Player player) {
251 PestControlNode node = new PestControlNode(player);
252
253 PestControlPanel panel = new PestControlPanel(player, node);
254 panel.open();
255
256 return node;
257 }
258
259 @Override
260 protected boolean finished() {
261 if (getTicks() == FINISH || getActiveSize() == 0) {
262 return true;
263 }
264
265 if (!inLobby()) {
266 if (portalSet.isEmpty()) {
267 return true;
268 }
269
270 if (voidKnight.isRegistered() && voidKnight.getCurrentHealth() <= 0) {
271 return true;
272 }
273 }
274
275 return false;
276 }
277
278 private void spawnMonsters() {
279 for (int index = 0; index < 5; index++) {
280 spawn(Utility.randomElement(RAVAGERS), BLUE_BOUNDS, 5);
281 }
282 for (int index = 0; index < 5; index++) {
283 spawn(Utility.randomElement(RAVAGERS), RED_BOUNDS, 5);
284 }
285 for (int index = 0; index < 5; index++) {
286 spawn(Utility.randomElement(RAVAGERS), YELLOW_BOUNDS, 5);
287 }
288 for (int index = 0; index < 5; index++) {
289 spawn(Utility.randomElement(RAVAGERS), PURPLE_BOUNDS, 5);
290 }
291 for (int index = 0; index < 2; index++) {
292 spawn(Utility.randomElement(RAVAGERS), KNIGHT_BOUNDS, 6);
293 }
294 }
295
296 private void spawn(int id, Position southWest, int size) {
297 Position target = RandomUtils.random(TraversalMap.getTraversableTiles(southWest, size, size));
298 Npc monster = new Npc(id, target);
299 monsters.add(monster);
300 add(monster);
301 }
302
303 private void agressiveMonsters() {
304 if (monsters.isEmpty())
305 return;
306 if (voidKnight == null)
307 return;
308 for (Npc monster : monsters) {
309 if (monster.getCombat().inCombat())
310 continue;
311 if (monster.getPosition().isWithinDistance(voidKnight.getPosition(), 10)) {
312 monster.getCombat().attack(voidKnight);
313 continue;
314 }
315 activities.keySet().forEach(mob -> {
316 if (!mob.isPlayer())
317 return;
318 if (monster.getPosition().isWithinDistance(mob.getPosition(), 8))
319 monster.getCombat().attack(mob);
320 });
321 }
322 }
323
324 private class Portal extends Npc {
325 Portal(int id, Position position) {
326 super(id, position);
327 walk = false;
328 getCombat().addListener(CANT_ATTACK);
329 }
330 }
331
332 public class PestControlNode extends Activity {
333
335 public int damage;
336 private final Player player;
337
338 private PestControlNode(Player player) {
339 super(1, Entity.DEFAULT_INSTANCE);
340 this.player = player;
341 }
342
343 @Override
344 protected void start() {
345 player.move(BOAT.transform(Utility.random(4), Utility.random(6)));
346 player.dialogueFactory.sendNpcChat(1756, "Go with strength!", "Defend the void knight and destroy the portals!", "You are our only hope!").execute();
347 }
348
349 @Override
350 public void finish() {
351 if (!inLobby() && !Area.inPestControl(player)) {
352 return;
353 }
354
355 getPanel().ifPresent(Activity_Panel::close);
356 player.move(OUTSIDE_BOAT_POSITION);
357 player.playerAssistant.restore();
358 player.animate(Animation.RESET, true);
359 player.graphic(Graphic.RESET, true);
360
361 if (inLobby()) {
362 return;
363 }
364
365 if (voidKnight.getCurrentHealth() <= 0) {
366 player.dialogueFactory.sendNpcChat(1756, "You let the Void Knight die!", "Keep him alive you noobs...").execute();
367 return;
368 }
369
370 if (portalSet.isEmpty()) {
371 if (damage == 0) {
372 player.dialogueFactory.sendNpcChat(1756, "You have disgraced your squad by not dealing any damage.", "As punishment, you get no points! Teamwork next time!").execute();
373 return;
374 }
375
376 if (damage < 50) {
377 player.dialogueFactory.sendNpcChat(1756, "You only dealt " + damage + " damage this round.", "You need to deal at least 50 damage to receive a reward.").execute();
378 return;
379 }
380
381 int points = PlayerRight.getBloodMoney(player) / 100;
382 AchievementHandler.activate(player, AchievementKey.PEST_CONTROL);
383 player.activityLogger.add(ActivityLog.PEST_CONTROL);
384 player.pestPoints += points;
385 player.dialogueFactory.sendNpcChat(1756, "You have beaten the minigame!", "You were rewarded with " + points + " pest control points.", "You now have: " + player.pestPoints + ".").execute();
386 } else {
387 player.dialogueFactory.sendNpcChat(1756, "You have run out of time!", "You failed the mission and don't get any points.").execute();
388 }
389 }
390
391 @Override
392 public void cleanup() {}
393
394 @Override
395 public ActivityType getType() {
396 return ActivityType.PEST_CONTROL;
397 }
398
399 }
400 @Override
401 public boolean canTeleport(Player player) {
402 player.send(new SendMessage("Talk to the void-knight next to the boat to leave."));
403 return false;
404 }
405
406 private final class PestControlPanel extends Activity_Panel {
407 private final PestControlNode node;
408
409 private PestControlPanel(Player player, PestControlNode node) {
410 super(player, "Pest Control");
411 this.node = node;
412 node.setPanel(this);
413 }
414
415 public void update() {
416 if (inLobby()) {
417 set(0, "Next Departure: <col=FF5500>" + Utility.getTime(getTicks()) + "</col>");
418 set(1, "Players Ready: <col=FF5500>" + getActiveSize() + "</col>");
419 set(2, "(Need <col=FF5500>" + manager.getMinimumRequired() + "</col> to " + manager.getPlayerCapacity() + " players)");
420 set(3, "Points: <col=FF5500>" + node.player.pestPoints + "</col>");
421 setFooter("Players Ready:");
422 setProgress((int) Utility.getPercentageAmount(getActiveSize(), manager.getPlayerCapacity()));
423 } else {
424 set(0, "Time remaining: <col=FF5500>" + Utility.getTime(getTicks()) + "</col>");
425 set(1, "Knight's health: <col=FF5500>" + voidKnight.getCurrentHealth() + "</col>");
426 set(2, "Damage: <col=FF5500>" + node.damage + "</col>");
427 int dead = 0;
428 for (int index = 0; index <= 3; index++) {
429 String value = "dead";
430 Portal portal = portals[index];
431 if (portal.getCurrentHealth() > 0) {
432 value = String.valueOf(portal.getCurrentHealth());
433 } else {
434 dead++;
435 }
436 set(3 + index, PORTAL_NAMES[index] + ": <col=FF5500>" + value + "</col>");
437 }
438 setFooter("Minigame Completion:");
439 setProgress((int) Utility.getPercentageAmount(dead, 4));
440 }
441 setItem(new Item(11666));
442 }
443 }
444
445}
Activity(int cooldown, int instance)
Definition Activity.java:92
Optional< Activity_Panel > getPanel()
void forEachActivity(BiConsumer< Mob, Activity > activity)
static void schedule(Task task)
Definition World.java:284
void move(Position position)
Definition Mob.java:377
static Position create(int x, int y, int z)
Position transform(int diffX, int diffY, int diffZ)
static< T > T randomElement(Collection< T > collection)
Definition Utility.java:285
static String getTime()
Definition Utility.java:178
static double getPercentageAmount(int progress, int total)
Definition Utility.java:73