public static void addDamage(Entity killer, Entity target, int damage) { if (!target.isDead()) { target.addToHitCount(killer, damage); } }
private static bool canCastSpell2(Player p, Entity target, int i, bool fakeNPC) { // fakeNPC is used to keep location when autocasting. if (fakeNPC) { return !p.isDead(); } if (target.isDead() || p.isDead() || target.isDestroyed() || p.isDestroyed()) { return false; } if (target is Npc) { if (((Npc)target).getHp() <= 0) { return false; } } if ((target is Player) && (p is Player)) { if (Location.inFightPits(target.getLocation()) && Location.inFightPits(target.getLocation())) { if (!Server.getMinigames().getFightPits().hasGameStarted()) { return false; } return true; } if (p.getDuel() != null) { if (((Player)target).getDuel() != null) { if (p.getDuel().getPlayer2().Equals(((Player)target)) && ((Player)target).getDuel().getPlayer2().Equals(p)) { if (p.getDuel().ruleEnabled(DuelSession.RULE.NO_MAGIC)) { return false; } if (p.getDuel().getStatus() == 6 && ((Player)target).getDuel().getStatus() == 6) { return true; } } } return false; } if (!Location.inWilderness(target.getLocation()) && !Location.inWilderness(p.getLocation())) return false; int killerWildLevel = p.getLocation().wildernessLevel(); int targetWildLevel = ((Player)target).getLocation().wildernessLevel(); int killerCombatLevel = p.getSkills().getCombatLevel(); int targetCombatLevel = ((Player)target).getSkills().getCombatLevel(); int highest = killerCombatLevel > targetCombatLevel ? killerCombatLevel : targetCombatLevel; int lowest = highest == killerCombatLevel ? targetCombatLevel : killerCombatLevel; int difference = (highest - lowest); if (difference > killerWildLevel || difference > targetWildLevel) { return false; } } return true; }
private static bool canCastSpell(Player p, Entity target, int i, bool fakeNPC) { // fakeNPC is used to keep location when autocasting. if (fakeNPC) { return !p.isDead(); } if (target.isDead() || p.isDead() || target.isDestroyed() || p.isDestroyed()) { return false; } if (target is Npc) { if (((Npc)target).getHp() <= 0) { return false; } if (i == 47) { p.getPackets().sendMessage("You cannot cast Teleblock upon an NPC."); return false; } } if ((target is Player) && (p is Player)) { if (Location.inFightPits(target.getLocation()) && Location.inFightPits(target.getLocation())) { if (!Server.getMinigames().getFightPits().hasGameStarted()) { return false; } return true; } if (p.getDuel() != null) { if (((Player)target).getDuel() != null) { if (p.getDuel().getPlayer2().Equals(((Player)target)) && ((Player)target).getDuel().getPlayer2().Equals(p)) { if (p.getDuel().ruleEnabled(DuelSession.RULE.NO_MAGIC)) { p.getPackets().sendMessage("Magical combat has been disabled in this duel!"); return false; } if (p.getDuel().getStatus() == 6 && ((Player)target).getDuel().getStatus() == 6) { return true; } } } p.getPackets().sendMessage("That isn't your opponent."); return false; } if (i == 47) { if (((Player)target).getTemporaryAttribute("teleblocked") != null) { p.getPackets().sendMessage("That player already has a teleportation block upon them."); return false; } } if (!Location.inWilderness(target.getLocation())) { p.getPackets().sendMessage("That player isn't in the wilderness."); return false; } if (!Location.inWilderness(p.getLocation())) { p.getPackets().sendMessage("You aren't in the wilderness."); return false; } int killerWildLevel = p.getLocation().wildernessLevel(); int targetWildLevel = ((Player)target).getLocation().wildernessLevel(); int killerCombatLevel = p.getSkills().getCombatLevel(); int targetCombatLevel = ((Player)target).getSkills().getCombatLevel(); int highest = killerCombatLevel > targetCombatLevel ? killerCombatLevel : targetCombatLevel; int lowest = highest == killerCombatLevel ? targetCombatLevel : killerCombatLevel; int difference = (highest - lowest); if (difference > killerWildLevel || difference > targetWildLevel) { ((Player)p).getPackets().sendMessage("You must move deeper into the wilderness to attack that player."); return false; } } if (!Location.inMultiCombat(target.getLocation())) { if (p.getAttacker() != null && !p.getAttacker().Equals(target)) { p.getPackets().sendMessage("You are already in combat!"); return false; } if (target.getAttacker() != null && !target.getAttacker().Equals(p)) { string type = target is Player ? "player" : "npc"; p.getPackets().sendMessage("That " + type + " is already in combat."); return false; } } if (p.getSkills().getCurLevel(Skills.SKILL.MAGIC) < SPELL_LEVEL[i]) { p.getPackets().sendMessage("You need a Magic level of " + SPELL_LEVEL[i] + " to cast that spell."); return false; } if (!hasRunes(p, RUNES[i], RUNE_AMOUNTS[i])) { p.getPackets().sendMessage("You do not have enough runes to cast that spell."); return false; } if (NEEDS_STAFF[i]) { if ((i != 38 && p.getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON) != STAFF[i]) || (i == 38 && p.getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON) != 8841 && p.getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON) != STAFF[i])) { p.getPackets().sendMessage("You need to wield " + STAFF_NAME[i] + " to cast this spell."); return false; } } if (i == 37) { if (p.getEquipment().getItemInSlot(ItemData.EQUIP.CAPE) != 2412) { p.getPackets().sendMessage("You need to wear the Cape of Saradomin to be able to cast Saradomin Strike."); return false; } } if (i == 38) { if (p.getEquipment().getItemInSlot(ItemData.EQUIP.CAPE) != 2413) { p.getPackets().sendMessage("You need to wear the Cape of Guthix to be able to cast Claws of Guthix."); return false; } } if (i == 39) { if (p.getEquipment().getItemInSlot(ItemData.EQUIP.CAPE) != 2414) { p.getPackets().sendMessage("You need to wear the Cape of Zamorak to be able to cast Flames of Zamorak."); return false; } } return true; }
public static void newMagicAttack(Player p, Entity target, int id, bool ancients) { int index = getSpellIndex(p, id, ancients); bool autoCasting = p.getTemporaryAttribute("autoCasting") != null; bool fakeNPC = target != null && target is Npc && ((Npc)target).getId() == 0; Entity lastAutocastEntity = null; bool frozen = false; if (index == -1) { return; } if (p.getTarget() == null) { if (autoCasting) { if (Location.inMultiCombat(p.getLocation())) { lastAutocastEntity = (Entity)p.getTemporaryAttribute("autocastEntity") == null ? null : (Entity)p.getTemporaryAttribute("autocastEntity"); if (lastAutocastEntity == null || lastAutocastEntity is Player) { p.removeTemporaryAttribute("autoCasting"); Combat.resetCombat(p, 1); return; } if (hitsMulti(p, index)) { Location location = (Location)p.getTemporaryAttribute("autocastLocation"); Entity newTarget = new Npc(0); newTarget.setLocation(location); p.setTarget(newTarget); newMagicAttack(p, newTarget, id, ancients); return; } } else { p.removeTemporaryAttribute("autoCasting"); Combat.resetCombat(p, 1); return; } } else { p.removeTemporaryAttribute("autoCasting"); Combat.resetCombat(p, 1); return; } } else { if (!canCastSpell(p, target, index, fakeNPC)) { p.removeTemporaryAttribute("autoCasting"); Combat.resetCombat(p, 1); return; } } int distance = 8; if (target is Player) { if (((Player)target).getSprites().getPrimarySprite() != -1) { distance = 8; } } if (!fakeNPC) { // we're actually attacking a real npc/player if (!p.getLocation().withinDistance(target.getLocation(), distance)) { p.getFollow().setFollowing(target); Event attemptMagicAttackEvent = new Event(500); int attemptMagicAttackCounter = 0; attemptMagicAttackEvent.setAction(() => { if (p.getLocation().withinDistance(target.getLocation(), distance) && p.getTarget() != null) { attemptMagicAttackEvent.stop(); newMagicAttack(p, target, id, ancients); return; } attemptMagicAttackCounter++; if (attemptMagicAttackCounter >= 12) { attemptMagicAttackEvent.stop(); } }); Server.registerEvent(attemptMagicAttackEvent); return; } } int timeSinceLastCast = autoCasting ? 3500 : 2000; if (Environment.TickCount - p.getLastMagicAttack() < timeSinceLastCast) { p.getWalkingQueue().resetWalkingQueue(); //return; } int time = p.getLastCombatType().Equals(Combat.CombatType.MAGE) ? 1550 : 600; if (Environment.TickCount - p.getLastAttack() < time) { int delay = p.getLastCombatType().Equals(Combat.CombatType.MAGE) ? 1350 : 800; Event attemptMagicAttackEvent = new Event(500); attemptMagicAttackEvent.setAction(() => { if (Environment.TickCount - p.getLastAttack() > delay) { attemptMagicAttackEvent.stop(); newMagicAttack(p, target, id, ancients); } }); Server.registerEvent(attemptMagicAttackEvent); p.getWalkingQueue().resetWalkingQueue(); p.getPackets().clearMapFlag(); p.setLastCombatType(Combat.CombatType.MAGE); return; } if (fakeNPC && !monsterInArea(p, target)) { p.removeTemporaryAttribute("autoCasting"); Combat.resetCombat(p, 1); return; } int endGfx = END_GFX[index]; double damage = Misc.random(CombatFormula.getMagicHit(p, target, getSpellMaxHit(p, index))); bool mp = false; bool magicProtect = mp; if (target is Player) { mp = ((Player)target).getPrayers().getHeadIcon() == PrayerData.MAGIC; } if (magicProtect) { damage *= 0.60; } if (p.getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON) == 8841) { damage *= 1.10; // void mace 10% hit increase. } if (damage == 0 && index != 41 && index != 42 && index != 43 && index != 44 && index != 45 && index != 46 && index != 47) { endGfx = 85; } if (!deleteRunes(p, RUNES[index], RUNE_AMOUNTS[index])) { p.setTarget(null); return; } p.getFollow().setFollowing(null); p.getWalkingQueue().resetWalkingQueue(); p.getPackets().clearMapFlag(); p.setFaceLocation(target.getLocation()); if (HANDS_GFX[index] != -1) { p.setLastGraphics(new Graphics(HANDS_GFX[index], 0, getStartingGraphicHeight(index))); } p.setLastAnimation(new Animation(SPELL_ANIM[index])); p.getPackets().closeInterfaces(); if (target is Player) { ((Player)target).getPackets().closeInterfaces(); } target.setAttacker(p); p.setTarget(target); target.setLastAttacked(Environment.TickCount); p.setLastAttack(Environment.TickCount); p.setLastMagicAttack(Environment.TickCount); p.setCombatTurns(p.getAttackSpeed()); Combat.setSkull(p, target); if (damage > 0) { frozen = freezeTarget(index, target); if (!frozen && index == 31) { endGfx = 1677; } } if (AIR_GFX[index] != -1 || ((index == 31 || index == 27) && target is Player && ((Player)target).getWalkingQueue().isRunning())) { sendProjectile(index, target, p); } if (damage > target.getHp()) { damage = target.getHp(); } if (index == 47 && Misc.random(2) == 0) { endGfx = 85; } Combat.checkIfWillDie(target, damage); Event doMagicAttackEvent = new Event(getSpellHitDelay(index)); doMagicAttackEvent.setAction(() => { doMagicAttackEvent.stop(); if (p == null || p.isDead() || !fakeNPC && (target.isDead() || target.isHidden() || target.isDestroyed())) { return; } if (target.isAutoRetaliating() && target.getTarget() == null && damage > 0) { if (target is Npc) { } else { if (((Player)target).getTemporaryAttribute("autoCastSpell") != null) { int autoCastSpell = (int)((Player)target).getTemporaryAttribute("autoCastSpell"); ((Player)target).setTemporaryAttribute("autoCasting", true); target.setTarget(p); MagicCombat.newMagicAttack((Player)target, p, autoCastSpell, ((Player)target).getTemporaryAttribute("autoCastAncients") != null); } } target.getFollow().setFollowing(p); target.setEntityFocus(p.getClientIndex()); if ((target.getCombatTurns() <= (target.getAttackSpeed() / 2) || target.getCombatTurns() >= (target.getAttackSpeed()))) { target.setCombatTurns(target.getAttackSpeed() / 2); } target.setTarget(p); if (target is Player) { ((Player)target).getWalkingQueue().resetWalkingQueue(); ((Player)target).getPackets().clearMapFlag(); } } addMagicXp(p, target, damage, index, true); target.setLastGraphics(new Graphics(endGfx, 0, getGroundHeight(index, endGfx))); if (index == 47 && endGfx != 85) { // teleblock if (target is Player) { teleblockPlayer(p, (Player)target); } } if (damage != 0) { Combat.checkRecoil(p, target, damage); Combat.checkSmite(p, target, damage); Combat.checkVengeance(p, target, damage); hitInMulti(p, target, index); applyMiasmicEffects(p, target, index); if ((target.getCombatTurns() > 2 || target.getCombatTurns() < 0) && !target.isDead()) { target.setLastAnimation(new Animation(target.getDefenceAnimation())); } if (index != 27) { target.hit((int)damage); if (index == 18 || index == 22 || index == 26 || index == 30) { p.heal(Convert.ToInt32(damage / 4)); } } else if (index == 27) { Event doHitEvent = new Event(1000); doHitEvent.setAction(() => { doHitEvent.stop(); target.hit((int)damage); }); Server.registerEvent(doHitEvent); } } }); Server.registerEvent(doMagicAttackEvent); if (p.getTemporaryAttribute("autoCasting") != null) { if (p.getTemporaryAttribute("autoCastSpell") != null) { if (id != (int)p.getTemporaryAttribute("autoCastSpell")) { p.setTarget(null); return; } } if (!fakeNPC) { p.setTemporaryAttribute("autocastLocation", target.getLocation()); p.setTemporaryAttribute("autocastEntity", target); } Event autoCastSpellEvent = new Event(3500); autoCastSpellEvent.setAction(() => { autoCastSpellEvent.stop(); if (p.getTemporaryAttribute("autoCasting") != null && p.getTemporaryAttribute("autoCastSpell") != null) { int autoCastSpell = (int)p.getTemporaryAttribute("autoCastSpell"); MagicCombat.newMagicAttack(p, p.getTarget(), autoCastSpell, p.getTemporaryAttribute("autoCastAncients") != null); } }); Server.registerEvent(autoCastSpellEvent); } else { p.setTarget(null); } }
public static void attack(Npc npc, Entity target) { if (npc.isDead() || npc.getOwner() == null || npc.isDestroyed() || target.isDead() || target.isDestroyed()) { return; } int damage = Misc.random(npc.getMaxHit()); int prayer = ((Player)target).getPrayers().getHeadIcon(); int hitDelay = npc.getHitDelay(); bool special = false; switch (npc.getId()) { case 2026: // Dharok int healthHit = (npc.getMaxHp() - npc.getHp()) / 2; damage = Misc.random(damage + healthHit); if (Misc.random(1) == 0) { if (damage < (npc.getMaxHp() / 3)) { damage = (npc.getMaxHp() / 4) + Misc.random(damage + healthHit) - (npc.getMaxHp() / 4); } } if (prayer == PrayerData.MELEE) { damage = 0; } break; case 2025: // Ahrim hitDelay = 1000; ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 156, 50, 40, 34, 60, target); if (Misc.random(3) == 0) { special = true; Skills.SKILL[] weakenableSkills = (Skills.SKILL[])Enum.GetValues(typeof(Skills.SKILL)); Skills.SKILL weakenedSkill = weakenableSkills[Misc.random(0, 2)]; int currentLevel = ((Player)target).getSkills().getCurLevel(weakenedSkill); int newLevel = currentLevel - Misc.random(((Player)target).getSkills().getMaxLevel(weakenedSkill) / 12); newLevel = Math.Max(0, newLevel); ((Player)target).getSkills().setCurLevel(weakenedSkill, newLevel); ((Player)target).getPackets().sendSkillLevel(weakenedSkill); } if (prayer == PrayerData.MAGIC) { damage = 0; } break; case 2027: // Guthan if (prayer == PrayerData.MELEE) { damage = 0; } if (Misc.random(3) == 0) { special = true; target.setLastGraphics(new Graphics(398)); npc.heal(Misc.random(damage)); } break; case 2030: // Verac if (Misc.random(1) == 0 && prayer != 0) { if (damage <= npc.getMaxHit() / 2) { damage += npc.getMaxHit() / 2; if (damage > npc.getMaxHit()) { damage = npc.getMaxHit(); } } } break; case 2029: // Torag if (Misc.random(3) == 0) { special = true; } if (prayer == PrayerData.MELEE) { damage = 0; } break; case 2028: // Karil hitDelay = 700; ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 27, 50, 40, 34, 40, target); if (Misc.random(10) == 0) { special = true; int agility = ((Player)target).getSkills().getCurLevel(Skills.SKILL.AGILITY); int newAgility = agility / 4; if (newAgility <= 1) newAgility = 1; ((Player)target).getSkills().setCurLevel(Skills.SKILL.AGILITY, newAgility); ((Player)target).getPackets().sendSkillLevel(Skills.SKILL.AGILITY); } if (Misc.random(1) == 0) { damage = damage > 0 ? damage : Misc.random(npc.getMaxHit()); } if (prayer == PrayerData.RANGE) { damage = 0; } break; } npc.setLastAnimation(new Animation(npc.getAttackAnimation())); target.setLastAttacked(Environment.TickCount); npc.setLastAttack(Environment.TickCount); npc.resetCombatTurns(); target.setAttacker(npc); if ((target.getCombatTurns() > 2 || target.getCombatTurns() < 0)) { target.setLastAnimation(new Animation(target.getDefenceAnimation())); } if (damage > target.getHp()) { damage = target.getHp(); } Event doHitEvent = new Event(hitDelay); doHitEvent.setAction(() => { if (npc.getId() == 2025) { if (special) { target.setLastGraphics(new Graphics(400, 0, 100)); ((Player)target).getPackets().sendMessage("You feel weakened."); } target.setLastGraphics(new Graphics(damage == 0 ? 85 : 157, 0, 100)); } else if (npc.getId() == 2027) { if (special) { if (!npc.isDead()) { int newHp = npc.getHp() + damage; if (newHp > npc.getMaxHp()) { newHp = npc.getMaxHp(); } npc.setHp(newHp); } } } else if (npc.getId() == 2029) { if (special) { target.setLastGraphics(new Graphics(399, 0, 100)); int energy = ((Player)target).getRunEnergy(); int newEnergy = energy - (int)(energy * 0.50); if (newEnergy < 0) { newEnergy = 0; } ((Player)target).getPackets().sendMessage("You feel drained of energy."); ((Player)target).setRunEnergy(newEnergy); ((Player)target).getPackets().sendEnergy(); } } else if (npc.getId() == 2028) { if (special) { target.setLastGraphics(new Graphics(399)); ((Player)target).getPackets().sendMessage("You feel less agile."); } } target.hit(damage); doHitEvent.stop(); }); }
public bool doSpecialAttack(Entity killer, Entity target) { int weapon = ((Player)killer).getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON); int currentPower = specialAmount; int neededPower = getRequiredAmount(weapon); bool rangeWeapon = false; if (!usingSpecial) { return false; } if (p.getDuel() != null) { if (p.getDuel().ruleEnabled(DuelSession.RULE.NO_SPECIAL_ATTACKS)) { p.getPackets().sendMessage("Special attacks have been disabled for this duel!"); usingSpecial = false; refreshBar(); return false; } } if (neededPower > currentPower) { ((Player)killer).getPackets().sendMessage("You don't have enough special power left."); usingSpecial = false; refreshBar(); return false; } double damage = -1; double damage2 = -1; double damage3 = -1; double damage4 = -1; bool doubleHit = false; int increasedMaxHit = 0; damage = CombatFormula.getSpecialMeleeHit((Player)killer, target, weapon); damage2 = CombatFormula.getSpecialMeleeHit((Player)killer, target, weapon); int hitDelay = killer.getHitDelay(); //int totalDamage = 0; int usingBow = ((Player)killer).getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON); int usingArrows = ((Player)killer).getEquipment().getItemInSlot(ItemData.EQUIP.ARROWS); bool usingRangePrayer = false; if (target is Player) { usingRangePrayer = ((Player)target).getPrayers().getHeadIcon() == PrayerData.RANGE; } switch (weapon) { case 4151: // Whip. killer.setLastAnimation(new Animation(1658)); target.setLastGraphics(new Graphics(341, 0, 100)); if (Misc.random(3) == 0 && damage > 0) { damage = p.getMaxHit(); } else { damage = 0; } if (target is Player) { int energy = ((Player)target).getRunEnergy() / 4; ((Player)killer).setRunEnergy(((Player)killer).getRunEnergy() + energy); ((Player)target).setRunEnergy(((Player)target).getRunEnergy() - energy); if (((Player)killer).getRunEnergy() > 100) { ((Player)killer).setRunEnergy(100); } if (((Player)target).getRunEnergy() < 0) { ((Player)target).setRunEnergy(0); } } break; case 1215: // Dragon daggers. case 1231: case 5680: case 5698: if (damage > 0) { damage = p.getMaxHit(20); damage2 = p.getMaxHit(20); } killer.setLastAnimation(new Animation(1062)); killer.setLastGraphics(new Graphics(252, 0, 100)); doubleHit = true; /*if (misc.random(3) == 0 && CombatFormula.getMeleeHit(p, target) > 0) { if (damage <= (CombatFormula.getMaxHit(p, 20) / 2) && damage2 <= (CombatFormula.getMaxHit(p, 20) / 2)) { damage = (CombatFormula.getMaxHit(p, 20) / 2) + (misc.randomDouble() * CombatFormula.getMaxHit(p, 20)) / 2); damage2 = (CombatFormula.getMaxHit(p, 20) / 2) + (misc.randomDouble() * CombatFormula.getMaxHit(p, 20)) / 2); } } else if (misc.random(2) == 0) { damage = 0; damage2 = 0; }*/ double a = damage + damage2; if (damage > target.getHp()) { damage = target.getHp(); } a -= damage; if (damage2 > a) { damage2 = a; } /*if (damage > target.getHp()) { int randomHp = misc.random(target.getHp()); damage = randomHp; damage2 = target.getHp() - randomHp; } else { int hpRemaining = target.getHp() - damage; if (damage2 > hpRemaining) { damage2 = hpRemaining; } }*/ break; case 1305: // Dragon longsword. killer.setLastAnimation(new Animation(1058)); killer.setLastGraphics(new Graphics(248, 0, 100)); damage = p.getMaxHit(30); break; case 11694: // Armadyl godsword. killer.setLastGraphics(new Graphics(1222, 0, 100)); killer.setLastAnimation(new Animation(7074)); damage += p.getMaxHit() * 0.25; break; case 11696: // Bandos godsword. killer.setLastGraphics(new Graphics(1223, 0, 100)); killer.setLastAnimation(new Animation(7073)); damage += p.getMaxHit() * 0.10; break; case 11698: // Saradomin godsword. killer.setLastGraphics(new Graphics(1220, 0, 100)); killer.setLastAnimation(new Animation(7071)); int newHp = (int)(damage * 0.50); int newPrayer = (int)(damage * 0.25); if (newHp < 10) { newHp = 10; } if (newPrayer < 5) { newPrayer = 5; } ((Player)killer).heal(newHp); ((Player)killer).getSkills().setCurLevel(Skills.SKILL.PRAYER, ((Player)killer).getSkills().getCurLevel(Skills.SKILL.PRAYER) + newPrayer); if (((Player)killer).getSkills().getCurLevel(Skills.SKILL.PRAYER) > ((Player)killer).getSkills().getMaxLevel(Skills.SKILL.PRAYER)) { ((Player)killer).getSkills().setCurLevel(Skills.SKILL.PRAYER, ((Player)killer).getSkills().getMaxLevel(Skills.SKILL.PRAYER)); } break; case 11700: // Zamorak godsword killer.setLastGraphics(new Graphics(1221, 0, 100)); killer.setLastAnimation(new Animation(7070)); target.setLastGraphics(new Graphics(369)); MagicCombat.freezeTarget(31, target); break; case 11730: // Saradomin sword target.setLastGraphics(new Graphics(1207, 0, 100)); killer.setLastAnimation(new Animation(7072)); increasedMaxHit = 16; break; case 1434: // Dragon mace hitDelay = 700; killer.setLastGraphics(new Graphics(251, 0, 75)); killer.setLastAnimation(new Animation(1060)); damage = p.getMaxHit(60); break; case 3204: // Dragon halberd // TODO halberd break; case 4587: // Dragon scimitar killer.setLastGraphics(new Graphics(347, 0, 100)); killer.setLastAnimation(new Animation(451)); if (target is Player) { if (((Player)target).getPrayers().getOverheadPrayer() >= 1 && ((Player)target).getPrayers().getOverheadPrayer() <= 3) { ((Player)target).getPrayers().setOverheadPrayer(0); ((Player)target).getPrayers().setHeadIcon(-1); ((Player)target).getPackets().sendMessage("The Dragon scimitar slashes through your prayer protection!"); ((Player)target).getPackets().sendConfig(95, 0); ((Player)target).getPackets().sendConfig(97, 0); ((Player)target).getPackets().sendConfig(98, 0); ((Player)target).getPackets().sendConfig(99, 0); ((Player)target).getPackets().sendConfig(100, 0); ((Player)target).getPackets().sendConfig(96, 0); } } break; case 14484: // Dragon claws doubleHit = true; killer.setLastGraphics(new Graphics(1950)); killer.setLastAnimation(new Animation(10961)); if (Misc.random(1) == 0 && damage > 0) { if (damage < p.getMaxHit(20) * 0.75) { damage = (p.getMaxHit(20) * 0.75 + (Misc.randomDouble() * (p.getMaxHit(20) * 0.25))); } } damage = (int)Math.Floor(damage); damage2 = (int)Math.Floor(damage * 0.50); damage3 = (int)Math.Floor(damage2 * 0.50); damage4 = (int)Math.Floor(damage3 + 1); break; case 1249: // Dragon spear //TODO leave due to noclipping? break; case 6739: // Dragon axe //TODO find emote and graphic break; case 7158: // Dragon 2h killer.setLastAnimation(new Animation(3157)); killer.setLastGraphics(new Graphics(559)); //TODO multi combat break; case 3101: // Rune claws killer.setLastGraphics(new Graphics(274)); break; case 4153: // Granite maul killer.setLastAnimation(new Animation(1667)); killer.setLastGraphics(new Graphics(340, 0, 100)); //doubleHit = true; break; case 10887: // Barrelchest anchor break; case 11061: // Ancient mace break; case 13902: // Statius' warhammer killer.setLastAnimation(new Animation(10505)); killer.setLastGraphics(new Graphics(1840)); damage += killer.getMaxHit() * 0.25; if (target is Player) { int defenceLevel = ((Player)target).getSkills().getCurLevel(Skills.SKILL.DEFENCE); int newDefence = (int)(defenceLevel * 0.30); if (newDefence < 1) { newDefence = 1; } ((Player)target).getSkills().setCurLevel(Skills.SKILL.DEFENCE, defenceLevel - newDefence); ((Player)target).getPackets().sendSkillLevel(Skills.SKILL.DEFENCE); } break; case 13899: // Vesta's longsword killer.setLastAnimation(new Animation(10502)); damage += killer.getMaxHit() * 0.20; break; case 13905: // Vesta's spear killer.setLastAnimation(new Animation(10499)); killer.setLastGraphics(new Graphics(1835)); break; case 13883: // Morrigans throwing axe break; case 13879: // Morrigans javelin case 8880: // Dorgeshuun crossbow break; case 861: // Magic shortbow case 859: // Magic longbow case 10284: // Magic composite bow rangeWeapon = true; if (p.getEquipment().getAmountInSlot(ItemData.EQUIP.ARROWS) < 2) { p.getPackets().sendMessage("You need 2 arrows to use the Magic bow special attack!"); return false; } damage = (int)CombatFormula.getRangeHit((Player)killer, target, usingBow, usingArrows); damage2 = (int)CombatFormula.getRangeHit((Player)killer, target, usingBow, usingArrows); damage *= 1.05; damage2 *= 1.05; if (usingRangePrayer) { damage *= 0.60; damage2 *= 0.60; } double a1 = damage + damage2; if (damage > target.getHp()) { damage = target.getHp(); } a1 -= damage; if (damage2 > a1) { damage2 = a1; } /*if (damage >= target.getHp()) { int randomHp = misc.random(target.getHp()); damage = randomHp; damage2 = target.getHp() - randomHp; } else { int hpRemaining = target.getHp() - damage; if (damage2 > hpRemaining) { damage2 = hpRemaining; } }*/ p.setLastAnimation(new Animation(1074)); p.setLastGraphics(new Graphics(256, 0, 90)); RangeCombat.deductArrow(killer); RangeCombat.deductArrow(killer); int arrowType = RangeCombat.getArrowType(killer); hitDelay = 1000; int MSpecCounter = 0; Event displayMSpecProjectileEvent = new Event(0); displayMSpecProjectileEvent.setAction(() => { RangeCombat.displayMSpecProjectile(killer, target); MSpecCounter++; if (MSpecCounter == 1) { displayMSpecProjectileEvent.setTick(500); p.setLastGraphics(new Graphics(256, 0, 90)); Event doMSpecHitEvent = new Event(900); doMSpecHitEvent.setAction(() => { doMSpecHitEvent.stop(); target.hit((int)damage2); RangeCombat.createGroundArrow(killer, target, arrowType); }); Server.registerEvent(doMSpecHitEvent); } else { displayMSpecProjectileEvent.stop(); return; } MSpecCounter++; }); Server.registerEvent(displayMSpecProjectileEvent); break; case 805: // Rune thrownaxe rangeWeapon = true; break; case 6724: // Seercull rangeWeapon = true; break; case 11235: // Dark bow rangeWeapon = true; if (p.getEquipment().getAmountInSlot(ItemData.EQUIP.ARROWS) < 2) { p.getPackets().sendMessage("You need 2 arrows to use the Dark bow!"); return false; } int minHit = 8; damage = (int)CombatFormula.getRangeHit((Player)killer, target, usingBow, usingArrows); damage2 = (int)CombatFormula.getRangeHit((Player)killer, target, usingBow, usingArrows); if (usingBow == 11235) { // Dark bow if (usingArrows == 11212) { // Dragon arrows minHit = usingRangePrayer ? 4 : 8; damage *= 1.50; damage2 *= 1.50; if (damage < minHit) { damage = minHit; } if (damage2 < minHit) { damage2 = minHit; } } else { // Other arrow minHit = usingRangePrayer ? 3 : 5; damage *= 1.30; damage2 *= 1.30; if (damage < minHit) { damage = minHit; } if (damage2 < minHit) { damage2 = minHit; } } } if (usingRangePrayer) { damage *= 0.60; damage2 *= 0.60; } double a2 = damage + damage2; if (damage > target.getHp()) { damage = target.getHp(); } a2 -= damage; if (damage2 > a2) { damage2 = a2; } /*if (damage >= target.getHp()) { int randomHp = misc.random(target.getHp()); damage = randomHp; damage2 = target.getHp() - randomHp; } else { int hpRemaining = target.getHp() - damage; if (damage2 > hpRemaining) { damage2 = hpRemaining; } }*/ p.setLastGraphics(new Graphics(RangeCombat.getDrawbackGraphic(killer), 0, 90)); RangeCombat.deductArrow(killer); RangeCombat.deductArrow(killer); hitDelay = RangeCombat.getHitDelay(killer, target); int delayHit = hitDelay; hitDelay = 1200; int arrowType1 = RangeCombat.getArrowType(killer); int DBSpecCounter = 0; Event DBSpecProjectile = new Event(0); DBSpecProjectile.setAction(() => { RangeCombat.displayDBSpecProjectile(killer, target); DBSpecCounter++; if (DBSpecCounter == 1) { DBSpecProjectile.setTick(200); Event rangeHitEvent = new Event(delayHit + 600); rangeHitEvent.setAction(() => { target.hit((int)damage2); rangeHitEvent.stop(); RangeCombat.createGroundArrow(killer, target, arrowType1); }); Server.registerEvent(rangeHitEvent); } else { DBSpecProjectile.stop(); return; } DBSpecCounter++; }); Server.registerEvent(DBSpecProjectile); break; } specialAmount -= neededPower; p.setSpecialAmount(specialAmount); usingSpecial = false; refreshBar(); killer.resetCombatTurns(); bool hitDouble = doubleHit; if (target is Player) { if (!rangeWeapon) { if (((Player)target).getPrayers().getHeadIcon() == PrayerData.MELEE) { damage = (int)(damage * 0.60); } } else { if (((Player)target).getPrayers().getHeadIcon() == PrayerData.RANGE) { damage = (int)(damage * 0.60); } } } damage = ((weapon == 4151) ? damage : (Misc.randomDouble() * damage)); damage2 = Misc.randomDouble() * damage2; int d = (int)((damage == 0 && weapon != 11730) ? 0 : (damage + increasedMaxHit)); int d2 = (int)damage2; int d3 = (int)damage3; // only used for d claws int d4 = (int)damage4; // only used for d claws if (canPoison(weapon)) { if (!target.isPoisoned() && Misc.random(5) == 0 && (hitDouble ? (d2 > 0 || d > 0) : d > 0)) { Server.registerEvent(new PoisonEvent(target, POISON_AMOUNT)); } } int hhitDelay = hitDelay; int totDamage = Convert.ToInt32(damage + damage2 + damage3 + damage4); Combat.checkIfWillDie(target, totDamage); Event hitEvent = new Event(hhitDelay); hitEvent.setAction(() => { hitEvent.stop(); if (!target.isDead()) { target.setLastAnimation(new Animation(target.getDefenceAnimation())); } target.hit(d); if (hitDouble) { target.hit(d2); } if (d3 != -1 || d4 != -1) { target.hit(d3); target.hit(d4); } Combat.checkRecoil(killer, target, totDamage); Combat.checkSmite(killer, target, totDamage); Combat.checkVengeance(killer, target, totDamage); Combat.addXp(killer, target, totDamage); }); Server.registerEvent(hitEvent); return true; }
private static bool canAttack(Entity killer, Entity target, bool usingRange) { if (target.isDead() || killer.isDead() || target.isDestroyed() || killer.isDestroyed()) { return false; } if (killer is Npc) { if (((Npc)killer).getId() < 2025 && ((Npc)killer).getId() > 2030) { if (!target.getLocation().inArea(((Npc)killer).getMinimumCoords().getX(), ((Npc)killer).getMinimumCoords().getY(), ((Npc)killer).getMaximumCoords().getX(), ((Npc)killer).getMaximumCoords().getY())) { return false; } } } if (target is Npc) { if (((Npc)target).getHp() <= 0) { return false; } if (((Npc)target).getId() >= 6222 && ((Npc)target).getId() <= 6228) { if (!usingRange && killer is Player) { ((Player)killer).getPackets().sendMessage("You are unable to reach the flying beast.."); return false; } } } if ((target is Player) && (killer is Player)) { if (Location.inFightPits(target.getLocation()) && Location.inFightPits(((Player)killer).getLocation())) { if (!Server.getMinigames().getFightPits().hasGameStarted()) { return false; } return true; } if (((Player)killer).getDuel() != null) { if (((Player)target).getDuel() != null) { if (((Player)killer).getDuel().getPlayer2().Equals(((Player)target)) && ((Player)target).getDuel().getPlayer2().Equals(((Player)killer))) { if (((Player)killer).getDuel().ruleEnabled(DuelSession.RULE.NO_MELEE)) { ((Player)killer).getPackets().sendMessage("Melee combat has been disabled in this duel!"); return false; } if (((Player)killer).getDuel().getStatus() == 6 && ((Player)target).getDuel().getStatus() == 6) { return true; } } } ((Player)killer).getPackets().sendMessage("That isn't your opponent."); return false; } else if (!Location.inWilderness(target.getLocation())) { ((Player)killer).getPackets().sendMessage("That player isn't in the wilderness."); return false; } else if (!Location.inWilderness(killer.getLocation())) { ((Player)killer).getPackets().sendMessage("You aren't in the wilderness."); return false; } int killerWildLevel = ((Player)killer).getLocation().wildernessLevel(); int targetWildLevel = ((Player)target).getLocation().wildernessLevel(); int killerCombatLevel = ((Player)killer).getSkills().getCombatLevel(); int targetCombatLevel = ((Player)target).getSkills().getCombatLevel(); int highest = killerCombatLevel > targetCombatLevel ? killerCombatLevel : targetCombatLevel; int lowest = highest == killerCombatLevel ? targetCombatLevel : killerCombatLevel; int difference = (highest - lowest); if (difference > killerWildLevel || difference > targetWildLevel) { ((Player)killer).getPackets().sendMessage("You must move deeper into the wilderness to attack that player."); return false; } } if (!Location.inMultiCombat(target.getLocation())) { if (killer.getAttacker() != null && !killer.getAttacker().Equals(target) && killer.getLastAttacked() > 0) { if (killer is Player) { ((Player)killer).getPackets().sendMessage("You are already in combat!"); } return false; } if (target.getAttacker() != null && !target.getAttacker().Equals(killer) && target.getLastAttacked() > 0) { if (killer is Player) { string type = target is Player ? "player" : "npc"; ((Player)killer).getPackets().sendMessage("That " + type + " is already in combat."); } return false; } } return true; }
public static void rangeCombatLoop(Entity killer, Entity target) { if (!hasValidBowArrow(killer)) { killer.setTarget(null); return; } int hitDelay = getHitDelay(killer, target); if (killer is Player) { ((Player)killer).getWalkingQueue().resetWalkingQueue(); ((Player)killer).getPackets().closeInterfaces(); ((Player)killer).getPackets().clearMapFlag(); ((Player)killer).setLastCombatType(Combat.CombatType.RANGE); } int drawback = getDrawbackGraphic(killer); if (drawback != -1) { killer.setLastGraphics(new Graphics(drawback, 0, 90)); } displayProjectile(killer, target); deductArrow(killer); int arrowType = getArrowType(killer); int usingBow = ((Player)killer).getEquipment().getItemInSlot(ItemData.EQUIP.WEAPON); int usingArrows = ((Player)killer).getEquipment().getItemInSlot(ItemData.EQUIP.ARROWS); int damage1 = Misc.random((int)getDamage((Player)killer, target, usingBow, usingArrows)); int damage2 = usingBow == DARK_BOW ? Misc.random((int)getDamage((Player)killer, target, usingBow, usingArrows)) : 0; /* * If the damage of the first attack will kill the target. * Make sure the target doesn't die from that first attack. * But instead split the attack into two attacks. */ if (damage1 >= target.getHp()) { int randomHp = Misc.random(target.getHp()); damage1 = randomHp; damage2 = target.getHp() - randomHp; } else { int hpRemaining = target.getHp() - damage1; if (damage2 > hpRemaining) { damage2 = hpRemaining; } } int totalDamage = damage1 + damage2; Combat.checkIfWillDie(target, (damage1 + damage2)); Event doRangedAttackEvent = new Event(hitDelay); doRangedAttackEvent.setAction(() => { int damage = damage1; if (getBowType(killer) == BOW_TYPE.CROSSBOW) { damage = applyBoltGraphic((Player)killer, target, damage1, arrowType); totalDamage = damage + damage2; } if ((target.getCombatTurns() > 2 || target.getCombatTurns() < 0) && !target.isDead()) { target.setLastAnimation(new Animation(target.getDefenceAnimation())); } target.hit(damage); Combat.addXp(killer, target, totalDamage); Combat.checkRecoil(killer, target, totalDamage); Combat.checkSmite(killer, target, totalDamage); Combat.checkVengeance(killer, target, totalDamage); if (killer is Player && arrowType != -1 && arrowType != BOLT_RACK) { createGroundArrow(killer, target, arrowType); } doRangedAttackEvent.stop(); }); Server.registerEvent(doRangedAttackEvent); //If the bow you are using is a darkbow do a second attack and animation. if (getBowType(killer) == BOW_TYPE.DARK_BOW) { deductArrow(killer); Event displayProjectileEvent = new Event(200); displayProjectileEvent.setAction(() => { displayProjectile(killer, target); displayProjectileEvent.stop(); }); Server.registerEvent(displayProjectileEvent); Event shootArrowEvent = new Event(hitDelay + 400); shootArrowEvent.setAction(() => { target.hit(damage2); if (killer is Player && arrowType != -1 && arrowType != BOLT_RACK) { createGroundArrow(killer, target, arrowType); } shootArrowEvent.stop(); }); Server.registerEvent(shootArrowEvent); } }
public static void attack(Npc npc, Entity target) { if (npc.isDead() || npc.isDestroyed() || target.isDead() || target.isDestroyed() || target.isDead()) { return; } int damage = Misc.random(npc.getMaxHit()); int prayer = ((Player)target).getPrayers().getHeadIcon(); int hitDelay = npc.getHitDelay(); int animation = npc.getAttackAnimation(); bool special = false; switch (npc.getId()) { case 6263: // Steelwill (bandos mage) hitDelay = 1000; animation = 65535; if (prayer == PrayerData.MAGIC) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1203, 50, 40, 34, 50, target); //npc.graphics(1201); break; case 6260: // Graardor (bandos) randomMessage(npc, BANDOS_SHOUTS); if (Misc.random(3) == 0) { special = true; hitDelay = 1000; animation = 7063; ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1200, 50, 40, 34, 50, target); if (prayer == PrayerData.RANGE) { damage = 0; } else { damage = Misc.random(35); } } else { if (prayer == PrayerData.MELEE) { damage = 0; } } break; case 6265: // Grimspike (bandos range) hitDelay = 1000; animation = 65535; if (prayer == PrayerData.RANGE) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1206, 50, 40, 34, 50, target); //npc.graphics(1201); break; case 6247: // Zilyana (sara boss) randomMessage(npc, SARADOMIN_SHOUTS); if (Misc.random(3) == 0) { animation = 6967; special = true; if (prayer == PrayerData.MAGIC) { damage = 0; } } else { if (prayer == PrayerData.MELEE) { damage = 0; } } break; case 6250: // Growler (sara mage) hitDelay = 1000; if (prayer == PrayerData.MAGIC) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1227, 50, 20, 27, 50, target); break; case 6252: // Bree (sara range) hitDelay = 1000; if (prayer == PrayerData.RANGE) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1227, 50, 20, 27, 50, target); //TODO all anims break; case 6203: // K'ril Tsutsaroth (zammy boss) randomMessage(npc, ZAMORAK_SHOUTS); if (prayer == PrayerData.MELEE) { damage = 0; } if (Misc.random(3) == 0) { animation = 6947; damage = Misc.random(49); if (prayer != 0 && damage < (49 / 2)) { damage = (49 / 2) + Misc.random(49 / 2); } } if (Misc.random(4) == 0) { if (!target.isPoisoned()) { if (damage > 0) { Server.registerEvent(new PoisonEvent(target, 16)); } } } break; case 6208: // Balfrug Kreeyath (zammy mage) hitDelay = 1200; if (prayer == PrayerData.MAGIC) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1213, 50, 20, 27, 70, target); // TODO attack anim break; case 6206: // Zakl'n Gritch (zammy range) hitDelay = 1200; if (prayer == PrayerData.RANGE) { damage = 0; } npc.setLastGraphics(new Graphics(1208)); ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1209, 50, 20, 27, 70, target); break; case 6222: // Kree'arra (armadyl boss) if (Misc.random(4) == 0) { npc.setForceText("Kraaaaw!"); } hitDelay = 1200; if (Misc.random(2) == 0 && npc.getAttacker() != null && npc.getAttacker().Equals(npc.getTarget())) { special = true; // Magic attack damage = Misc.random(21); if (prayer == PrayerData.MAGIC) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1198, 50, 20, 27, 70, target); } else if (npc.getAttacker() != null && npc.getAttacker().Equals(npc.getTarget())) { //range attack if (prayer == PrayerData.RANGE) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1197, 50, 20, 27, 70, target); } else { // do melee attack because they arent attacking kree arra damage = Misc.random(25); if (prayer == PrayerData.MELEE) { damage = 0; } animation = 6977; } break; case 6223: // Armadyl mage hitDelay = 1200; if (prayer == PrayerData.MAGIC) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1199, 50, 20, 27, 70, target); break; case 6225: // Armadyl range hitDelay = 1200; if (prayer == PrayerData.RANGE) { damage = 0; } ((Player)target).getPackets().sendProjectile(npc.getLocation(), target.getLocation(), 32, 1190, 50, 20, 27, 70, target); break; } if (animation != 65535) { npc.setLastAnimation(new Animation(animation)); } target.setLastAttacked(Environment.TickCount); npc.setLastAttack(Environment.TickCount); target.setAttacker(npc); npc.resetCombatTurns(); if (damage > target.getHp()) { damage = target.getHp(); } int hit = damage; Event attackEvent = new Event(hitDelay); attackEvent.setAction(() => { attackEvent.stop(); if (npc.getId() == 6263) { target.setLastGraphics(new Graphics(hit > 0 ? 166 : 85, 0, 100)); } else if (npc.getId() == 6260) { if (special) { target.setLastGraphics(new Graphics(hit > 0 ? 160 : 65535, 0, 100)); } } else if (npc.getId() == 6247) { if (special) { if (hit < 1) { return; } else { target.setLastGraphics(new Graphics(1207, 0, 100)); npc.setCombatTurns(npc.getAttackSpeed() * 2); } } } else if (npc.getId() == 6208) { if (hit == 0) { target.setLastGraphics(new Graphics(85, 0, 100)); } } else if (npc.getId() == 6222) { if (special) { target.setLastGraphics(new Graphics(hit == 0 ? 85 : 65535, 0, 100)); } } if ((target.getCombatTurns() > 2 || target.getCombatTurns() < 0)) { target.setLastAnimation(new Animation(target.getDefenceAnimation())); } target.hit(hit); }); Server.registerEvent(attackEvent); }
public void followEntity() { if (follower == null || entity.isDead() || follower.isDead() || follower.isDestroyed()) { follower = null; return; } if (follower.getLocation().withinDistance(entity.getLocation(), 1)) { return; } if (follower is Player) { if (follower.getEntityFocus() == -1 || follower.getEntityFocus() != entity.getClientIndex()) { entity.setEntityFocus(follower.getClientIndex()); } if (!follower.getLocation().withinDistance(entity.getLocation(), 15)) { setFollowing(null); return; } } //TODO: Starting from here organize all this crap properly. bool sameCoords = false; int x = entity.getLocation().getX(); int y = entity.getLocation().getY(); int targetX = follower.getLocation().getX(); int targetY = follower.getLocation().getY(); int newX = x; int newY = y; if (x == targetX && y == targetY) { sameCoordWait++; if (sameCoordWait < 2) { return; } if (sameCoordWait == 2) { if (Misc.random(3) == 0) { newY--; } else if (Misc.random(3) == 1) { newY++; } else if (Misc.random(3) == 2) { newX--; } else if (Misc.random(3) == 3) { newX++; } sameCoords = true; sameCoordWait = 0; } } if (!sameCoords) { if (targetX > x && targetY == y) { newX++; } else if (targetX < x && targetY == y) { newX--; } else if (targetX == x && targetY > y) { newY++; } else if (targetX == x && targetY < y) { newY--; } else if (targetX > x && targetY > y) { newX++; newY++; } else if (targetX < x && targetY < y) { newX--; newY--; } else if (targetX > x && targetY < y) { newX++; newY--; } else if (targetX < x && targetY > y) { newX--; newY++; } } //if (entity.getLocation().withinDistance(follower.getLocation(), Combat.npcUsesRange((Npc)entity) ? 30 : Combat.getNPCSize(entity, follower))) { // return; //} if (entity is Npc) { Location newLoc = new Location(newX, newY, entity.getLocation().getZ()); if (!newLoc.inArea(((Npc)entity).getMinimumCoords().getX(), ((Npc)entity).getMinimumCoords().getY(), ((Npc)entity).getMaximumCoords().getX(), ((Npc)entity).getMaximumCoords().getY())) { follower = null; return; } if (!sameCoords && newX == targetX && newY == targetY) { return; } } if (follower.getEntityFocus() == -1 || follower.getEntityFocus() != entity.getClientIndex()) { entity.setEntityFocus(follower.getClientIndex()); } /* * if (!entity.getLocation().withinDistance(follower.getLocation())) { * if (((Player)follower).getSummonedNPC() == npc) { * npc.setLastAnimation(new Animation(8298); * npc.setLastGraphics(new Graphics(NPCSizes.getNpcSize(npc.getId()) > 0 ? 1315 : 1314); * npc.setLocation(new Location(targetX, targetY, following.getLocation().getZ())); * npc.setEntityFocus(following.getClientIndex()); * return; * } * }*/ if (entity is Npc) { //npc following a player. ((Npc)entity).getSprites().setSprites(Misc.direction(x, y, newX, newY), -1); if (((Npc)entity).getSprites().getPrimarySprite() != -1) { int sprite = ((Npc)entity).getSprites().getPrimarySprite() >> 1; ((Npc)entity).getSprites().setSprites(sprite, -1); ((Npc)entity).setLocation(new Location(newX, newY, ((Npc)entity).getLocation().getZ())); } } else { //player following a player int diffX = targetX - x; int diffY = targetY - y; //if(Math.Max(Math.Abs(diffX), Math.Abs(diffY)) <= 1) return; //1 step away or on top of player, no need to follow //Try to fix this up to make it look more natural. Because just using the else statement looks ugly. //TODO: Must add sprite direction detection for it to know which way the person is standing so it would be behind him. if (diffX == 0 && diffY == -2) { //go down diffY = -1; } else if (diffX == 0 && diffY == 2) { //go up diffY = 1; } else if (diffX == -2 && diffY == 0) { //go left diffX = -1; } else if (diffX == 2 && diffY == 0) { //go right diffX = 1; } else if ((diffX == 2 && diffY == -2) || (diffX == 2 && diffY == -1) || (diffX == 1 && diffY == -2)) { //left down, down 1 left 2 or down 2 right 1 diffX = 1; diffY = -1; } else if ((diffX == -2 && diffY == 2) || (diffX == -2 && diffY == 1) || (diffX == -1 && diffY == 2)) { //left up, up 1 left 2 or up 2 left 1 diffX = -1; diffY = 1; } else if ((diffX == 2 && diffY == 2) || (diffX == 2 && diffY == 1) || (diffX == 1 && diffY == 2)) { //up right, up 1 right 2, up 2 right 1 diffX = 1; diffY = 1; } else if ((diffX == -2 && diffY == -2) || (diffX == -1 && diffY == -2) || (diffX == -2 && diffY == -1)) { //down left, down 2 left 1 or down 1 right 2 diffX = -1; diffY = -1; } else { if (diffX < 0) { diffX++; } else if (diffX > 0) { diffX--; } if (diffY < 0) { diffY++; } else if (diffY > 0) { diffY--; } } ((Player)entity).getWalkingQueue().forceWalk(diffX, diffY); } }