package com.asteria.game.character.combat.ranged; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.ADAMANT_ARROW; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.BRONZE_ARROW; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.IRON_ARROW; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.MITHRIL_ARROW; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.RUNE_ARROW; import static com.asteria.game.character.combat.ranged.CombatRangedAmmo.STEEL_ARROW; import java.util.Arrays; import com.asteria.game.character.player.Player; import com.asteria.game.item.Item; import com.asteria.game.item.container.Equipment; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; /** * The enumerated type that holds all of the ranged bows and the ammo they are * permitted to use. * * @author lare96 <http://github.org/lare96> */ public enum CombatRangedBow { SHORTBOW(841, BRONZE_ARROW, IRON_ARROW), LONGBOW(839, BRONZE_ARROW, IRON_ARROW), OAK_SHORTBOW(843, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW), OAK_LONGBOW(845, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW), WILLOW_SHORTBOW(849, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW), WILLOW_LONGBOW(847, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW), MAPLE_SHORTBOW(853, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW), MAPLE_LONGBOW(851, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW), YEW_SHORTBOW(857, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW, RUNE_ARROW), YEW_LONGBOW(855, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW, RUNE_ARROW), MAGIC_SHORTBOW(861, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW, RUNE_ARROW), MAGIC_LONGBOW(859, BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW, ADAMANT_ARROW, RUNE_ARROW); /** * The multimap that holds all of our ranged weapons and their respective * ranged ammo that they are permitted to shoot. For this multimap we use a * {@link HashMultimap} instead of your traditional * {@link LinkedListMultimap} or {@link ArrayListMultimap} for constant time * when checking for arrows. This collection is immutable which means that * no elements can be added or removed from it. */ private static final ImmutableMultimap<Integer, CombatRangedAmmo> WEAPONS = ImmutableMultimap.copyOf(get()); /** * The item identification for this ranged weapon. */ private final int id; /** * The array of ammo that this ranged weapon is permitted to use. */ private final CombatRangedAmmo[] ammo; /** * Creates a new {@link CombatRangedBow}. * * @param id * the item identification for this ranged weapon. * @param ammo * the array of ammo for this ranged weapon. */ private CombatRangedBow(int id, CombatRangedAmmo... ammo) { this.id = id; this.ammo = ammo; } /** * Retrieves the {@link Multimap} that holds the contents of this * enumeration. * * @return the multimap that holds the contents of this enumeration. */ private static Multimap<Integer, CombatRangedAmmo> get() { Multimap<Integer, CombatRangedAmmo> map = HashMultimap.create(); Arrays.stream(values()).forEach($it -> map.putAll($it.id, Arrays.asList($it.ammo))); return map; } /** * The static boolean method that determines if {@code player} wielding * {@code bow} can fire {@code ammo} with it. * * @param player * the player this is being determined for. * @param ammo * the ammo the player is using. * @return {@code true} if the player can use the ammo, {@code false} * otherwise. */ public static boolean canUse(Player player, CombatRangedAmmo ammo) { Item $it = player.getEquipment().get(Equipment.WEAPON_SLOT); if ($it == null) return true; ImmutableCollection<CombatRangedAmmo> values = WEAPONS.get($it.getId()); if (values.isEmpty()) return true; if (!values.contains(ammo)) { boolean needsPlural = !ammo.toString().endsWith("s"); player.getMessages().sendMessage("You cannot use " + ammo + "" + (needsPlural ? "s" : "") + " with this ranged weapon."); return false; } return true; } /** * Gets the item identification for this ranged weapon. * * @return the item identification. */ public final int getId() { return id; } /** * Gets the array of ammo that this ranged weapon is permitted to use. * * @return the array of ammo for this ranged weapon. */ public final CombatRangedAmmo[] getAmmo() { return ammo; } }