80public class DuelArenaActivity
extends Activity {
83 private static final Position[] ARENAS = {
91 private static final Position[] OBSTACLE_ARENAS = {
98 private static final Position HOSPITAL_BEDS_SOUTHWEST =
new Position(3361, 3272);
113 private DuelPanel playerPanel;
116 private DuelPanel opponentPanel;
119 private final DuelArenaListener listener =
new DuelArenaListener(
this);
122 private boolean rewarded;
128 private Player winner, loser;
130 public boolean hasLoser;
133 super(1,
Entity.DEFAULT_INSTANCE);
134 this.session = session;
135 this.player = player;
136 this.opponent = opponent;
144 duel.playerPanel =
new DuelPanel(duel, player);
145 duel.opponentPanel =
new DuelPanel(duel, opponent);
157 if (!session.accepted) {
174 player.speak(
"FIGHT!");
175 opponent.speak(
"FIGHT!");
183 opponentPanel.open();
186 player.speak(String.valueOf(
getTicks() / 2));
187 opponent.speak(String.valueOf(
getTicks() / 2));
193 unequipItems(player);
194 unequipItems(opponent);
196 player.playerAssistant.restore();
197 opponent.playerAssistant.restore();
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));
204 position =
TraversalMap.getRandomTraversableTile(position, 18, 9);
205 if (position ==
null) {
209 player.move(position);
211 if (position ==
null) {
215 opponent.move(position);
216 player.face(opponent);
217 opponent.face(player);
219 player.move(
TraversalMap.getRandomTraversableTile(ARENAS[0].transform(-3, -3), 3, 3));
220 opponent.move(
TraversalMap.getRandomTraversableTile(ARENAS[0].transform(3, -3), 3, 3));
234 player.playerAssistant.restore();
235 opponent.playerAssistant.restore();
237 player.move(
TraversalMap.getRandomTraversableTile(HOSPITAL_BEDS_SOUTHWEST, 14, 7));
240 opponent.move(
TraversalMap.getRandomTraversableTile(HOSPITAL_BEDS_SOUTHWEST, 14, 7));
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);
251 opponentPanel.close();
255 winner.message(
"You are victorious!");
256 loser.message(
"You lost!");
258 reward(winner, loser,
false);
263 opponentPanel.close();
266 player.graphic(
Graphic.RESET,
true);
269 opponent.graphic(
Graphic.RESET,
true);
279 if (!session.accepted) {
287 if (mob.equals(player)) {
290 }
else if (mob.equals(opponent)) {
298 if (!session.accepted) {
306 if (player.equals(
this.player)) {
309 }
else if (player.equals(opponent)) {
310 winner = this.player;
316 public boolean canLogout(
Player player) {
317 if (!session.accepted) {
324 player.send(
new SendMessage(
"You cannot logout in the duel arena!"));
329 public boolean canDrinkPotions(
Player player) {
330 if (!session.accepted) {
331 player.exchangeSession.
reset(ExchangeSessionType.DUEL);
332 opponent.exchangeSession.
reset(ExchangeSessionType.DUEL);
337 if (
rules.contains(DuelRule.NO_DRINKS)) {
338 player.send(
new SendMessage(
"Potions have been disabled!"));
345 public boolean canUsePrayer(Player player) {
346 if (!session.accepted) {
347 player.exchangeSession.reset(ExchangeSessionType.DUEL);
348 opponent.exchangeSession.
reset(ExchangeSessionType.DUEL);
353 if (
rules.contains(DuelRule.NO_PRAYER)) {
354 player.send(
new SendMessage(
"Prayer has been disabled!"));
362 public boolean canEat(Player player, FoodData foodType) {
363 if (!session.accepted) {
364 player.exchangeSession.reset(ExchangeSessionType.DUEL);
365 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
370 if (
rules.contains(DuelRule.NO_FOOD)) {
371 player.send(
new SendMessage(
"Food has been disabled!"));
378 public boolean canUseSpecial(Player player) {
379 if (!session.accepted) {
380 player.exchangeSession.reset(ExchangeSessionType.DUEL);
381 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
386 if (
rules.contains(DuelRule.NO_SPECIAL_ATTACK)) {
387 player.send(
new SendMessage(
"Special attacks have been disabled!"));
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);
406 if (
rules.contains(DuelRule.LOCK_ITEMS)) {
407 player.send(
new SendMessage(
"Item switching has been disabled!"));
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!"));
419 if (
rules.contains(DuelRule.ONLY_FUN_WEAPONS) && !DuelUtils.hasFunWeapon(player, item)) {
420 player.send(
new SendMessage(
"You can only use fun weapons!"));
424 if (
rules.contains(DuelRule.NO_WEAPON) && type.getSlot() == Equipment.WEAPON_SLOT) {
425 player.send(
new SendMessage(
"Weapons have been disabled!"));
429 if (
rules.contains(DuelRule.NO_SHIELD) && type.getSlot() == Equipment.SHIELD_SLOT) {
430 player.send(
new SendMessage(
"Shields have been disabled!"));
434 if (
rules.contains(DuelRule.NO_AMMO) && type.getSlot() == Equipment.ARROWS_SLOT) {
435 player.send(
new SendMessage(
"Ammo has been disabled!"));
439 if (
rules.contains(DuelRule.NO_HEAD) && type.getSlot() == Equipment.HEAD_SLOT) {
440 player.send(
new SendMessage(
"Helms have been disabled!"));
444 if (
rules.contains(DuelRule.NO_CAPE) && type.getSlot() == Equipment.CAPE_SLOT) {
445 player.send(
new SendMessage(
"Capes have been disabled!"));
449 if (
rules.contains(DuelRule.NO_NECKLACE) && type.getSlot() == Equipment.AMULET_SLOT) {
450 player.send(
new SendMessage(
"Amulets hae been disabled!"));
454 if (
rules.contains(DuelRule.NO_BODY) && type.getSlot() == Equipment.CHEST_SLOT) {
455 player.send(
new SendMessage(
"Chest items have been disabled!"));
459 if (
rules.contains(DuelRule.NO_LEGS) && type.getSlot() == Equipment.LEGS_SLOT) {
460 player.send(
new SendMessage(
"Leg items have been disabled!"));
464 if (
rules.contains(DuelRule.NO_GLOVES) && type.getSlot() == Equipment.HANDS_SLOT) {
465 player.send(
new SendMessage(
"Gloves have been disabled!"));
469 if (
rules.contains(DuelRule.NO_BOOTS) && type.getSlot() == Equipment.FEET_SLOT) {
470 player.send(
new SendMessage(
"Boots have been disabled!"));
474 if (
rules.contains(DuelRule.NO_RINGS) && type.getSlot() == Equipment.RING_SLOT) {
475 player.send(
new SendMessage(
"Rings have been disabled!"));
482 private void unequipItems(Player player) {
483 if (!session.accepted) {
484 player.exchangeSession.reset(ExchangeSessionType.DUEL);
485 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
490 if (
rules.contains(DuelRule.NO_WEAPON) && player.equipment.hasWeapon()) {
491 player.equipment.unequip(Equipment.WEAPON_SLOT);
494 if (
rules.contains(DuelRule.NO_HEAD) && player.equipment.hasHead()) {
495 player.equipment.unequip(Equipment.HEAD_SLOT);
498 if (
rules.contains(DuelRule.NO_CAPE) && player.equipment.hasCape()) {
499 player.equipment.unequip(Equipment.CAPE_SLOT);
502 if (
rules.contains(DuelRule.NO_NECKLACE) && player.equipment.hasAmulet()) {
503 player.equipment.unequip(Equipment.AMULET_SLOT);
506 if (
rules.contains(DuelRule.NO_AMMO) && player.equipment.hasAmmo()) {
507 player.equipment.unequip(Equipment.ARROWS_SLOT);
510 if (
rules.contains(DuelRule.NO_BODY) && player.equipment.hasChest()) {
511 player.equipment.unequip(Equipment.CHEST_SLOT);
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);
522 if (player.equipment.hasShield()) {
523 player.equipment.unequip(Equipment.SHIELD_SLOT);
527 if (
rules.contains(DuelRule.NO_LEGS) && player.equipment.hasLegs()) {
528 player.equipment.unequip(Equipment.LEGS_SLOT);
531 if (
rules.contains(DuelRule.NO_GLOVES) && player.equipment.hasHands()) {
532 player.equipment.unequip(Equipment.HANDS_SLOT);
535 if (
rules.contains(DuelRule.NO_BOOTS) && player.equipment.hasFeet()) {
536 player.equipment.unequip(Equipment.FEET_SLOT);
539 if (
rules.contains(DuelRule.NO_RINGS) && player.equipment.hasRing()) {
540 player.equipment.unequip(Equipment.RING_SLOT);
546 protected boolean clickObject(Player player, ObjectInteractionEvent event) {
547 switch(event.getObject().getId()) {
551 if (!session.accepted) {
552 player.exchangeSession.reset(ExchangeSessionType.DUEL);
553 opponent.exchangeSession.reset(ExchangeSessionType.DUEL);
558 if (
rules.contains(DuelRule.NO_FORFEIT)) {
559 player.send(
new SendMessage(
"Forfeiting has been disabled!"));
564 player.send(
new SendMessage(
"You can't forfeit yet!"));
569 if (player.equals(
this.player)) {
572 }
else if (player.equals(opponent)) {
573 winner = this.player;
584 return Optional.of(listener);
597 private void reward(
Player player,
Player loser, Item[] reward,
long value,
boolean stalemate) {
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);
606 private void reward(
Player winner,
Player loser,
boolean stalemate) {
607 Objects.requireNonNull(winner);
608 Objects.requireNonNull(loser);
611 Objects.requireNonNull(winnerContainer);
614 Objects.requireNonNull(loserContainer);
617 reward(loser, loser, loserContainer.toArray(), loserContainer.containerValue(
PriceType.
VALUE),
true);
618 reward(winner, loser, winnerContainer.toArray(), winnerContainer.containerValue(
PriceType.
VALUE),
true);
620 winner.inventory.
addOrDrop(winnerContainer.toArray());
621 loser.inventory.
addOrDrop(loserContainer.toArray());
625 ItemContainer rewardContainer =
new ItemContainer(28, ItemContainer.StackPolicy.STANDARD);
627 rewardContainer.addAll(loserContainer.toArray());
628 value += loserContainer.containerValue(PriceType.VALUE);
629 reward(loser, loser, rewardContainer.toArray(), value,
false);
631 value += winnerContainer.containerValue(PriceType.VALUE);
632 rewardContainer.addAll(winnerContainer.toArray());
633 reward(winner, loser, rewardContainer.toArray(), value,
false);
635 winner.inventory.
addOrDrop(rewardContainer.toArray());
645 playerPanel.update();
646 opponentPanel.update();
653 private final Player player;
656 super(player,
"Duel Arena");
657 this.activity = activity;
658 this.player = player;
662 Player dueler = player.equals(activity.player) ? activity.player : activity.opponent;
663 Player duelee = !player.equals(activity.player) ? activity.player : activity.opponent;
665 if (!activity.started) {
666 set(0,
"Dueling with: <col=FF5500>" +
Utility.formatName(duelee.
getName()) +
"</col>");
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:");
677 setItem(
new Item(4049));
680 private String accuracy(Player dueler, Player duelee) {
681 CombatStrategy<? super Player> strategy = dueler.getStrategy();
682 CombatType type = strategy.getCombatType();
684 dueler.getCombat().addModifier(strategy);
685 double attackRoll = rollOffensive(dueler, duelee, type.getFormula());
686 double defenceRoll = rollDefensive(dueler, duelee, type.getFormula());
687 dueler.getCombat().removeModifier(strategy);
689 double chance = attackRoll / (attackRoll + defenceRoll);
690 double accuracy = (int) (chance * 10000) / 100.0;
691 return String.valueOf(accuracy) +
"%";