package com.asteria.game.character.combat.effect; import java.util.HashMap; import java.util.Map; import java.util.Optional; import com.asteria.game.NodeType; import com.asteria.game.character.CharacterNode; import com.asteria.game.character.Hit; import com.asteria.game.character.HitType; import com.asteria.game.character.PoisonType; import com.asteria.game.character.npc.NpcDefinition; import com.asteria.game.character.player.Player; import com.asteria.game.item.Item; /** * The combat effect applied when a character needs to be poisoned. * * @author lare96 <http://github.com/lare96> */ public final class CombatPoisonEffect extends CombatEffect { /** * The collection of weapons mapped to their respective poison types. */ public static final Map<Integer, PoisonType> TYPES = new HashMap<>(); /** * The amount of times this player has been hit. */ private int amount; /** * Creates a new {@link CombatPoisonEffect}. */ public CombatPoisonEffect() { super(30); } @Override public boolean apply(CharacterNode t) { if (t.isPoisoned() || t.getPoisonType() == null) return false; if (t.getType() == NodeType.PLAYER) { Player player = (Player) t; if (player.getPoisonImmunity().get() > 0) return false; player.getMessages().sendMessage("You have been poisoned!"); } t.getPoisonDamage().set(t.getPoisonType().getDamage()); return true; } @Override public boolean removeOn(CharacterNode t) { return !t.isPoisoned(); } @Override public void process(CharacterNode t) { amount--; t.damage(new Hit(t.getPoisonDamage().get(), HitType.POISON)); if (amount == 0) { amount = 4; t.getPoisonDamage().decrementAndGet(); } } @Override public boolean onLogin(CharacterNode t) { return t.isPoisoned(); } /** * Gets the {@link PoisonType} for {@code item} wrapped in an optional. If a * poison type doesn't exist for the item then an empty optional is * returned. * * @param item * the item to get the poison type for. * @return the poison type for this item wrapped in an optional, or an empty * optional if no poison type exists. */ public static Optional<PoisonType> getPoisonType(Item item) { if (item == null || item.getId() < 1 || item.getAmount() < 1) return Optional.empty(); return Optional.ofNullable(TYPES.get(item.getId())); } /** * Gets the {@link PoisonType} for {@code npc} wrapped in an optional. If a * poison type doesn't exist for the NPC then an empty optional is returned. * * @param npc * the NPC to get the poison type for. * @return the poison type for this NPC wrapped in an optional, or an empty * optional if no poison type exists. */ public static Optional<PoisonType> getPoisonType(int npc) { NpcDefinition def = NpcDefinition.DEFINITIONS[npc]; if (def == null || !def.isAttackable() || !def.isPoisonous()) return Optional.empty(); if (def.getCombatLevel() < 75) return Optional.of(PoisonType.DEFAULT_NPC); if (def.getCombatLevel() < 200) return Optional.of(PoisonType.STRONG_NPC); return Optional.of(PoisonType.SUPER_NPC); } }