RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
DuelArenaActivity.java
1package com.osroyale.content.activity.impl.duelarena;
2
3import com.osroyale.content.activity.Activity;
4import com.osroyale.content.activity.ActivityDeathType;
5import com.osroyale.content.activity.ActivityType;
6import com.osroyale.content.activity.panel.ActivityPanel;
7import com.osroyale.content.activity.panel.Activity_Panel;
8import com.osroyale.content.consume.FoodData;
9import com.osroyale.content.event.impl.ObjectInteractionEvent;
10import com.osroyale.game.Animation;
11import com.osroyale.game.Graphic;
12import com.osroyale.game.world.entity.Entity;
13import com.osroyale.game.world.entity.combat.CombatType;
14import com.osroyale.game.world.entity.combat.strategy.CombatStrategy;
15import com.osroyale.game.world.entity.mob.Mob;
16import com.osroyale.game.world.entity.mob.player.Player;
17import com.osroyale.game.world.entity.mob.player.exchange.ExchangeSessionType;
18import com.osroyale.game.world.entity.mob.player.exchange.duel.StakeSession;
19import com.osroyale.game.world.items.Item;
20import com.osroyale.game.world.items.containers.ItemContainer;
21import com.osroyale.game.world.items.containers.equipment.Equipment;
22import com.osroyale.game.world.items.containers.equipment.EquipmentType;
23import com.osroyale.game.world.items.containers.pricechecker.PriceType;
24import com.osroyale.game.world.pathfinding.TraversalMap;
25import com.osroyale.game.world.position.Position;
26import com.osroyale.net.packet.out.SendEntityHintArrow;
27import com.osroyale.net.packet.out.SendItemOnInterface;
28import com.osroyale.net.packet.out.SendMessage;
29import com.osroyale.net.packet.out.SendString;
30import com.osroyale.util.Utility;
31
32import java.util.Objects;
33import java.util.Optional;
34
35import static com.osroyale.game.world.entity.combat.attack.FormulaFactory.rollDefensive;
36import static com.osroyale.game.world.entity.combat.attack.FormulaFactory.rollOffensive;
37
79
80public class DuelArenaActivity extends Activity {
81
83 private static final Position[] ARENAS = {
84 new Position(3345, 3251),
85 new Position(3378, 3251),
86 new Position(3345, 3213),
87 new Position(3379, 3213)
88 };
89
91 private static final Position[] OBSTACLE_ARENAS = {
92 new Position(3376, 3251),
93 new Position(3345, 3231),
94 new Position(3376, 3213)
95 };
96
98 private static final Position HOSPITAL_BEDS_SOUTHWEST = new Position(3361, 3272);
99
101 public final DuelRules rules = new DuelRules();
102
104 private final StakeSession session;
105
107 final Player player;
108
110 final Player opponent;
111
113 private DuelPanel playerPanel;
114
116 private DuelPanel opponentPanel;
117
119 private final DuelArenaListener listener = new DuelArenaListener(this);
120
122 private boolean rewarded;
123
125 public boolean started;
126
128 private Player winner, loser;
129
130 public boolean hasLoser;
131
132 private DuelArenaActivity(StakeSession session, Player player, Player opponent) {
133 super(1, Entity.DEFAULT_INSTANCE);
134 this.session = session;
135 this.player = player;
136 this.opponent = opponent;
137 }
138
139 public static DuelArenaActivity create(StakeSession session, Player player, Player opponent) {
140 DuelArenaActivity duel = new DuelArenaActivity(session, player, opponent);
141 duel.pause();
142 duel.add(player);
143 duel.add(opponent);
144 duel.playerPanel = new DuelPanel(duel, player);
145 duel.opponentPanel = new DuelPanel(duel, opponent);
146 return duel;
147 }
148
149 @Override
150 public void sequence() {
151 super.sequence();
152
153 if (isPaused()) {
154 return;
155 }
156
157 if (!session.accepted) {
158 player.exchangeSession.reset(ExchangeSessionType.DUEL);
159 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
160 removeAll(player, opponent);
161 return;
162 }
163
164 if (getTicks() < 0) {
165 return;
166 }
167
168 if (getTicks() == 0) {
169 if (started) {
171 return;
172 }
173
174 player.speak("FIGHT!");
175 opponent.speak("FIGHT!");
176 started = true;
177
178 // 10 minutes, has to be x2 because 2 players sequence this activity
179 cooldown(2000);
180 } else if (!started && getTicks() <= 6 && getTicks() % 2 == 0) {
181 if (getTicks() == 6) {
182 playerPanel.open();
183 opponentPanel.open();
184 }
185
186 player.speak(String.valueOf(getTicks() / 2));
187 opponent.speak(String.valueOf(getTicks() / 2));
188 }
189 }
190
191 @Override
192 protected void start() {
193 unequipItems(player);
194 unequipItems(opponent);
195
196 player.playerAssistant.restore();
197 opponent.playerAssistant.restore();
198
199 if (rules.contains(DuelRule.OBSTACLES)) {
200 player.move(TraversalMap.getRandomTraversableTile(OBSTACLE_ARENAS[0].transform(-3, -3), 3, 3));
201 opponent.move(TraversalMap.getRandomTraversableTile(OBSTACLE_ARENAS[0].transform(3, -3), 3, 3));
202 } else if (rules.contains(DuelRule.NO_MOVEMENT)) {
203 Position position = ARENAS[0].transform(-9, -7);
204 position = TraversalMap.getRandomTraversableTile(position, 18, 9);
205 if (position == null) {
207 return;
208 }
209 player.move(position);
210 position = TraversalMap.getRandomNonDiagonal(position);
211 if (position == null) {
213 return;
214 }
215 opponent.move(position);
216 player.face(opponent);
217 opponent.face(player);
218 } else {
219 player.move(TraversalMap.getRandomTraversableTile(ARENAS[0].transform(-3, -3), 3, 3));
220 opponent.move(TraversalMap.getRandomTraversableTile(ARENAS[0].transform(3, -3), 3, 3));
221 }
222
223 player.send(new SendEntityHintArrow(opponent, false));
224 opponent.send(new SendEntityHintArrow(player, false));
225 cooldown(8);
226 }
227
228 @Override
229 public void finish() {
230 if (rewarded) {
231 return;
232 }
233
234 player.playerAssistant.restore();
235 opponent.playerAssistant.restore();
236
237 player.move(TraversalMap.getRandomTraversableTile(HOSPITAL_BEDS_SOUTHWEST, 14, 7));
238 player.send(new SendEntityHintArrow(opponent, true));
239
240 opponent.move(TraversalMap.getRandomTraversableTile(HOSPITAL_BEDS_SOUTHWEST, 14, 7));
241 opponent.send(new SendEntityHintArrow(player, true));
242
243 if (winner == null || loser == null) {
244 player.message("The duel was a stalemate!");
245 opponent.message("The duel was a stalemate!");
246 reward(player, opponent, true);
247 rewarded = true;
248 removeAll(player, opponent);
249
250 playerPanel.close();
251 opponentPanel.close();
252 return;
253 }
254
255 winner.message("You are victorious!");
256 loser.message("You lost!");
257
258 reward(winner, loser, false);
259 rewarded = true;
260 removeAll(player, opponent);
261
262 playerPanel.close();
263 opponentPanel.close();
264
265 player.animate(Animation.RESET, true);
266 player.graphic(Graphic.RESET, true);
267
268 opponent.animate(Animation.RESET, true);
269 opponent.graphic(Graphic.RESET, true);
270 }
271
272 @Override
273 public void cleanup() {}
274
275 @Override
276 public void onDeath(Mob mob) {
277 hasLoser = true;
278
279 if (!session.accepted) {
280 player.exchangeSession.reset(ExchangeSessionType.DUEL);
281 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
282 removeAll(player, opponent);
283 return;
284 }
285
287 if (mob.equals(player)) {
288 winner = opponent;
289 loser = player;
290 } else if (mob.equals(opponent)) {
291 winner = player;
292 loser = opponent;
293 }
294 }
295
296 @Override
297 public void onLogout(Player player) {
298 if (!session.accepted) {
299 player.exchangeSession.reset(ExchangeSessionType.DUEL);
300 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
301 removeAll(player, opponent);
302 return;
303 }
304
306 if (player.equals(this.player)) {
307 winner = opponent;
308 loser = this.player;
309 } else if (player.equals(opponent)) {
310 winner = this.player;
311 loser = opponent;
312 }
313 }
314
315 @Override
316 public boolean canLogout(Player player) {
317 if (!session.accepted) {
318 player.exchangeSession.reset(ExchangeSessionType.DUEL);
319 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
320 removeAll(player, opponent);
321 return true;
322 }
323
324 player.send(new SendMessage("You cannot logout in the duel arena!"));
325 return false;
326 }
327
328 @Override
329 public boolean canDrinkPotions(Player player) {
330 if (!session.accepted) {
331 player.exchangeSession.reset(ExchangeSessionType.DUEL);
332 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
333 removeAll(player, opponent);
334 return true;
335 }
336
337 if (rules.contains(DuelRule.NO_DRINKS)) {
338 player.send(new SendMessage("Potions have been disabled!"));
339 return false;
340 }
341 return true;
342 }
343
344 @Override
345 public boolean canUsePrayer(Player player) {
346 if (!session.accepted) {
347 player.exchangeSession.reset(ExchangeSessionType.DUEL);
348 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
349 removeAll(player, opponent);
350 return true;
351 }
352
353 if (rules.contains(DuelRule.NO_PRAYER)) {
354 player.send(new SendMessage("Prayer has been disabled!"));
355 return false;
356 }
357
358 return true;
359 }
360
361 @Override
362 public boolean canEat(Player player, FoodData foodType) {
363 if (!session.accepted) {
364 player.exchangeSession.reset(ExchangeSessionType.DUEL);
365 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
366 removeAll(player, opponent);
367 return true;
368 }
369
370 if (rules.contains(DuelRule.NO_FOOD)) {
371 player.send(new SendMessage("Food has been disabled!"));
372 return false;
373 }
374 return true;
375 }
376
377 @Override
378 public boolean canUseSpecial(Player player) {
379 if (!session.accepted) {
380 player.exchangeSession.reset(ExchangeSessionType.DUEL);
381 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
382 removeAll(player, opponent);
383 return true;
384 }
385
386 if (rules.contains(DuelRule.NO_SPECIAL_ATTACK)) {
387 player.send(new SendMessage("Special attacks have been disabled!"));
388 return false;
389 }
390 return true;
391 }
392
393 @Override
394 public boolean canEquipItem(Player player, Item item, EquipmentType type) {
395 if (!session.accepted) {
396 player.exchangeSession.reset(ExchangeSessionType.DUEL);
397 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
398 removeAll(player, opponent);
399 return true;
400 }
401
402 if (type == null) {
403 return false;
404 }
405
406 if (rules.contains(DuelRule.LOCK_ITEMS)) {
407 player.send(new SendMessage("Item switching has been disabled!"));
408 return false;
409 }
410
411 if (rules.contains(DuelRule.ONLY_WHIP_DDS)) {
412 final String name = item.getName() == null ? "null" : item.getName().toLowerCase();
413 if (!name.contains("dragon dagger") && !name.contains("abyssal whip") && !name.contains("abyssal tentacle")) {
414 player.send(new SendMessage("You can only use a whip or dragon dagger!"));
415 return false;
416 }
417 }
418
419 if (rules.contains(DuelRule.ONLY_FUN_WEAPONS) && !DuelUtils.hasFunWeapon(player, item)) {
420 player.send(new SendMessage("You can only use fun weapons!"));
421 return false;
422 }
423
424 if (rules.contains(DuelRule.NO_WEAPON) && type.getSlot() == Equipment.WEAPON_SLOT) {
425 player.send(new SendMessage("Weapons have been disabled!"));
426 return false;
427 }
428
429 if (rules.contains(DuelRule.NO_SHIELD) && type.getSlot() == Equipment.SHIELD_SLOT) {
430 player.send(new SendMessage("Shields have been disabled!"));
431 return false;
432 }
433
434 if (rules.contains(DuelRule.NO_AMMO) && type.getSlot() == Equipment.ARROWS_SLOT) {
435 player.send(new SendMessage("Ammo has been disabled!"));
436 return false;
437 }
438
439 if (rules.contains(DuelRule.NO_HEAD) && type.getSlot() == Equipment.HEAD_SLOT) {
440 player.send(new SendMessage("Helms have been disabled!"));
441 return false;
442 }
443
444 if (rules.contains(DuelRule.NO_CAPE) && type.getSlot() == Equipment.CAPE_SLOT) {
445 player.send(new SendMessage("Capes have been disabled!"));
446 return false;
447 }
448
449 if (rules.contains(DuelRule.NO_NECKLACE) && type.getSlot() == Equipment.AMULET_SLOT) {
450 player.send(new SendMessage("Amulets hae been disabled!"));
451 return false;
452 }
453
454 if (rules.contains(DuelRule.NO_BODY) && type.getSlot() == Equipment.CHEST_SLOT) {
455 player.send(new SendMessage("Chest items have been disabled!"));
456 return false;
457 }
458
459 if (rules.contains(DuelRule.NO_LEGS) && type.getSlot() == Equipment.LEGS_SLOT) {
460 player.send(new SendMessage("Leg items have been disabled!"));
461 return false;
462 }
463
464 if (rules.contains(DuelRule.NO_GLOVES) && type.getSlot() == Equipment.HANDS_SLOT) {
465 player.send(new SendMessage("Gloves have been disabled!"));
466 return false;
467 }
468
469 if (rules.contains(DuelRule.NO_BOOTS) && type.getSlot() == Equipment.FEET_SLOT) {
470 player.send(new SendMessage("Boots have been disabled!"));
471 return false;
472 }
473
474 if (rules.contains(DuelRule.NO_RINGS) && type.getSlot() == Equipment.RING_SLOT) {
475 player.send(new SendMessage("Rings have been disabled!"));
476 return false;
477 }
478
479 return true;
480 }
481
482 private void unequipItems(Player player) {
483 if (!session.accepted) {
484 player.exchangeSession.reset(ExchangeSessionType.DUEL);
485 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
486 removeAll(player, opponent);
487 return;
488 }
489
490 if (rules.contains(DuelRule.NO_WEAPON) && player.equipment.hasWeapon()) {
491 player.equipment.unequip(Equipment.WEAPON_SLOT);
492 }
493
494 if (rules.contains(DuelRule.NO_HEAD) && player.equipment.hasHead()) {
495 player.equipment.unequip(Equipment.HEAD_SLOT);
496 }
497
498 if (rules.contains(DuelRule.NO_CAPE) && player.equipment.hasCape()) {
499 player.equipment.unequip(Equipment.CAPE_SLOT);
500 }
501
502 if (rules.contains(DuelRule.NO_NECKLACE) && player.equipment.hasAmulet()) {
503 player.equipment.unequip(Equipment.AMULET_SLOT);
504 }
505
506 if (rules.contains(DuelRule.NO_AMMO) && player.equipment.hasAmmo()) {
507 player.equipment.unequip(Equipment.ARROWS_SLOT);
508 }
509
510 if (rules.contains(DuelRule.NO_BODY) && player.equipment.hasChest()) {
511 player.equipment.unequip(Equipment.CHEST_SLOT);
512 }
513
514 if (rules.contains(DuelRule.NO_SHIELD)) {
515 if (player.equipment.hasWeapon()) {
516 Item weapon = player.equipment.getWeapon();
517 if (weapon.isTwoHanded()) {
518 player.equipment.unequip(Equipment.WEAPON_SLOT);
519 }
520 }
521
522 if (player.equipment.hasShield()) {
523 player.equipment.unequip(Equipment.SHIELD_SLOT);
524 }
525 }
526
527 if (rules.contains(DuelRule.NO_LEGS) && player.equipment.hasLegs()) {
528 player.equipment.unequip(Equipment.LEGS_SLOT);
529 }
530
531 if (rules.contains(DuelRule.NO_GLOVES) && player.equipment.hasHands()) {
532 player.equipment.unequip(Equipment.HANDS_SLOT);
533 }
534
535 if (rules.contains(DuelRule.NO_BOOTS) && player.equipment.hasFeet()) {
536 player.equipment.unequip(Equipment.FEET_SLOT);
537 }
538
539 if (rules.contains(DuelRule.NO_RINGS) && player.equipment.hasRing()) {
540 player.equipment.unequip(Equipment.RING_SLOT);
541 }
542
543 }
544
545 @Override
546 protected boolean clickObject(Player player, ObjectInteractionEvent event) {
547 switch(event.getObject().getId()) {
548 case 3111:
549 case 3113:
550 case 3203:
551 if (!session.accepted) {
552 player.exchangeSession.reset(ExchangeSessionType.DUEL);
553 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
554 removeAll(player, opponent);
555 return true;
556 }
557
558 if (rules.contains(DuelRule.NO_FORFEIT)) {
559 player.send(new SendMessage("Forfeiting has been disabled!"));
560 return true;
561 }
562
563 if (!started) {
564 player.send(new SendMessage("You can't forfeit yet!"));
565 return true;
566 }
567
569 if (player.equals(this.player)) {
570 winner = opponent;
571 loser = this.player;
572 } else if (player.equals(opponent)) {
573 winner = this.player;
574 loser = opponent;
575 }
576 return true;
577
578 }
579 return false;
580 }
581
582 @Override
583 protected Optional<DuelArenaListener> getListener() {
584 return Optional.of(listener);
585 }
586
587 @Override
588 public ActivityType getType() {
589 return ActivityType.DUEL_ARENA;
590 }
591
592 @Override
593 public ActivityDeathType deathType() {
594 return ActivityDeathType.SAFE;
595 }
596
597 private void reward(Player player, Player loser, Item[] reward, long value, boolean stalemate) {
598 player.send(new SendString("<col=E1981F>Total Value: " + Utility.formatDigits(value), 31709));
599 player.send(new SendString(loser.getName(), 31706));
600 player.send(new SendString(loser.skills.getCombatLevel(), 31707));
601 player.send(new SendItemOnInterface(31708, reward));
602 player.send(new SendString(stalemate ? "The duel was a stalemate!" : player.equals(loser) ? "You lost!" : "You are victorious!", 31705));
603 player.interfaceManager.open(31700, false);
604 }
605
606 private void reward(Player winner, Player loser, boolean stalemate) {
607 Objects.requireNonNull(winner);
608 Objects.requireNonNull(loser);
609
610 ItemContainer winnerContainer = session.item_containers.get(winner);
611 Objects.requireNonNull(winnerContainer);
612
613 ItemContainer loserContainer = session.item_containers.get(loser);
614 Objects.requireNonNull(loserContainer);
615
616 if (stalemate) {
617 reward(loser, loser, loserContainer.toArray(), loserContainer.containerValue(PriceType.VALUE), true);
618 reward(winner, loser, winnerContainer.toArray(), winnerContainer.containerValue(PriceType.VALUE), true);
619
620 winner.inventory.addOrDrop(winnerContainer.toArray());
621 loser.inventory.addOrDrop(loserContainer.toArray());
622 } else {
623 long value = 0;
624
625 ItemContainer rewardContainer = new ItemContainer(28, ItemContainer.StackPolicy.STANDARD);
626
627 rewardContainer.addAll(loserContainer.toArray());
628 value += loserContainer.containerValue(PriceType.VALUE);
629 reward(loser, loser, rewardContainer.toArray(), value, false);
630
631 value += winnerContainer.containerValue(PriceType.VALUE);
632 rewardContainer.addAll(winnerContainer.toArray());
633 reward(winner, loser, rewardContainer.toArray(), value, false);
634
635 winner.inventory.addOrDrop(rewardContainer.toArray());
636 }
637 }
638
639 @Override
640 public void update() {
641 if (!started || getTicks() == FINISH || isPaused()) {
642 return;
643 }
644
645 playerPanel.update();
646 opponentPanel.update();
647 ActivityPanel.update(playerPanel);
648 ActivityPanel.update(opponentPanel);
649 }
650
651 private static class DuelPanel extends Activity_Panel {
652 private final DuelArenaActivity activity;
653 private final Player player;
654
655 DuelPanel(DuelArenaActivity activity, Player player) {
656 super(player, "Duel Arena");
657 this.activity = activity;
658 this.player = player;
659 }
660
661 public void update() {
662 Player dueler = player.equals(activity.player) ? activity.player : activity.opponent;
663 Player duelee = !player.equals(activity.player) ? activity.player : activity.opponent;
664
665 if (!activity.started) {
666 set(0, "Dueling with: <col=FF5500>" + Utility.formatName(duelee.getName()) + "</col>");
667 setProgress(-1);
668 } else {
669 set(0, "Time remaining: <col=FF5500>" + Utility.getTime(activity.getTicks() / 2) + "</col>");
670 set(2, "Your accuracy: <col=FF5500>" + accuracy(dueler, duelee) + "</col>");
671 set(3, "Your max hit: <col=FF5500>" + dueler.playerAssistant.getMaxHit(duelee, dueler.getStrategy().getCombatType()) + "</col>");
672 set(5, "Opponent's accuracy: <col=FF5500>" + accuracy(duelee, dueler) + "</col>");
673 set(6, "Opponent's max hit: <col=FF5500>" + duelee.playerAssistant.getMaxHit(dueler, duelee.getStrategy().getCombatType()) + "</col>");
674 setFooter("Opponent health:");
675 setProgress((int) Utility.getPercentageAmount(duelee.getCurrentHealth(), duelee.getMaximumHealth()));
676 }
677 setItem(new Item(4049));
678 }
679
680 private String accuracy(Player dueler, Player duelee) {
681 CombatStrategy<? super Player> strategy = dueler.getStrategy();
682 CombatType type = strategy.getCombatType();
683
684 dueler.getCombat().addModifier(strategy);
685 double attackRoll = rollOffensive(dueler, duelee, type.getFormula());
686 double defenceRoll = rollDefensive(dueler, duelee, type.getFormula()); //what is this exactly? this class duel arena? just a panel
687 dueler.getCombat().removeModifier(strategy);
688
689 double chance = attackRoll / (attackRoll + defenceRoll);
690 double accuracy = (int) (chance * 10000) / 100.0;
691 return String.valueOf(accuracy) + "%";
692 }
693
694 }
695
696}
Activity(int cooldown, int instance)
Definition Activity.java:92
static void update(Player player, int amount, String title, String footer, String... strings)
Position transform(int diffX, int diffY, int diffZ)
static String formatDigits(final int amount)
Definition Utility.java:78
static String getTime()
Definition Utility.java:178
static double getPercentageAmount(int progress, int total)
Definition Utility.java:73