package net.scapeemulator.game.model.npc;
import net.scapeemulator.game.model.World;
import net.scapeemulator.game.model.mob.Animation;
import net.scapeemulator.game.model.mob.Mob;
import net.scapeemulator.game.model.mob.combat.AttackStyle;
import net.scapeemulator.game.model.mob.combat.AttackType;
import net.scapeemulator.game.model.mob.combat.CombatHandler;
import net.scapeemulator.game.model.mob.combat.DelayedMagicHit;
import net.scapeemulator.game.model.player.skills.magic.DamageSpell;
import net.scapeemulator.game.model.player.skills.prayer.HeadIcon;
public class NPCCombatHandler extends CombatHandler<NPC> {
public NPCCombatHandler(NPC npc) {
super(npc);
attackStyle = AttackStyle.SHARED;
setRawAttackType(npc.getDefinition().getAttackType());
// autoCast = npc.getDefinition().getAutoCast();
}
@Override
public boolean canAttack(Mob target) {
return mob.alive() && target.alive();
}
@Override
public boolean attack() {
if (combatDelay > 0) {
return false;
}
boolean shouldHit = shouldHit();
switch (getNextAttackType()) {
case MAGIC:
if (target.getHeadIcon() == HeadIcon.MAGIC) {
shouldHit = false;
}
break;
case SLASH:
case STAB:
case CRUSH:
if (target.getHeadIcon() == HeadIcon.MELEE) {
shouldHit = false;
}
break;
case RANGE:
if (target.getHeadIcon() == HeadIcon.RANGED) {
shouldHit = false;
}
break;
default:
break;
}
int damage = !shouldHit ? 0 : 1 + (int) (Math.random() * getMaxHit());
if (nextSpell != null) {
((DamageSpell)nextSpell).cast(mob, target, damage);
mob.playAnimation(new Animation(mob.getDefinition().getAttackEmote()));
nextSpell = autoCast;
} else {
mob.playAnimation(new Animation(mob.getDefinition().getAttackEmote()));
damage = damage > target.getCurrentHitpoints() ? target.getCurrentHitpoints() : damage;
hitTarget(damage);
}
combatDelay = mob.getDefinition().getAttackDelay();
return true;
}
private int getMaxHit() {
int level = 0;
int equipmentBonus = 0;
switch (getNextAttackType()) {
case MAGIC:
if (nextSpell instanceof DamageSpell) {
return ((DamageSpell) nextSpell).getMaxHit();
}
return 0;
case RANGE:
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.RANGED);
level += 9;
break;
case CRUSH:
case SLASH:
case STAB:
equipmentBonus = mob.getCombatBonuses().getStrengthBonus();
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.STRENGTH);
level += 9;
break;
}
return (int) (0.5 + ((level * (64.0 + equipmentBonus)) / 640));
}
@Override
public int attackRoll() {
int level = 0;
int equipmentBonus = 0;
switch (getNextAttackType()) {
case MAGIC:
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.MAGIC);
equipmentBonus = mob.getCombatBonuses().getAttackBonus(AttackType.MAGIC);
level += 8;
break;
case RANGE:
equipmentBonus = mob.getCombatBonuses().getAttackBonus(AttackType.RANGE);
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.RANGED);
level += 9;
break;
case CRUSH:
case SLASH:
case STAB:
equipmentBonus = mob.getCombatBonuses().getAttackBonus(getNextAttackType());
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.ATTACK);
level += 9;
break;
}
return level * (64 + equipmentBonus);
}
@Override
public int defenceRoll(AttackType other) {
int level = 0;
int equipmentBonus = 0;
switch (other) {
case MAGIC:
equipmentBonus = mob.getCombatBonuses().getDefenceBonus(AttackType.MAGIC);
level = (int) ((mob.getSkillSet().getCurrentLevel(NPCSkillSet.DEFENCE) + 9) * 0.3);
level += (int) (mob.getSkillSet().getCurrentLevel(NPCSkillSet.MAGIC) * 0.7);
break;
case RANGE:
case CRUSH:
case SLASH:
case STAB:
equipmentBonus = mob.getCombatBonuses().getDefenceBonus(other);
level = mob.getSkillSet().getCurrentLevel(NPCSkillSet.DEFENCE);
level += 9;
break;
}
return level * (64 + equipmentBonus);
}
@Override
public Animation getDefendAnimation() {
return new Animation(mob.getDefinition().getDefendEmote());
}
@Override
public int getAttackRange() {
return mob.getDefinition().getAttackRange();
}
@Override
public boolean shouldRetaliate() {
return target == null && noRetaliate < 1;
}
}