public static double getDamage(Entity killer, Entity target) { if (killer is Npc) { int maxDamage = killer.getMaxHit(); if (maxDamage > target.getHp()) { maxDamage = target.getHp(); } if (target is Player) { NpcData npcDef = NpcData.forId(((Npc)killer).getId()); int npcAttackStyle = ((Npc)killer).getAttackType(); if (((Player)target).getPrayers().getHeadIcon() == PrayerData.MELEE && npcAttackStyle == NpcData.MELEE) { return(0); } else if (misc.random((int)CombatFormula.getNPCMeleeAttack((Npc)killer)) < misc.random((int)CombatFormula.getMeleeDefence((Player)target, (Player)target))) { return(0); } } return(misc.random(maxDamage)); } else { if (target is Npc) { if (misc.random((int)CombatFormula.getMeleeAttack((Player)killer)) < misc.random((int)CombatFormula.getNPCMeleeDefence((Npc)target))) { return(0); } } double damage = CombatFormula.getMeleeHit((Player)killer, target); if (target is Player) { if (((Player)target).getPrayers().getHeadIcon() == PrayerData.MELEE) { damage = (int)(damage * 0.60); } } if (damage > target.getHp()) { damage = target.getHp(); } return(damage); } }
private static double getDamage(Player killer, Entity target, int usingBow, int usingArrows) { double damage = CombatFormula.getRangeHit(killer, target, usingBow, usingArrows); if (target is Player) { int prayerType = ((Player)target).getPrayers().getHeadIcon(); if (prayerType == PrayerData.RANGE) { return(damage * 0.60); } else { return(damage); } } return(damage); }
public static void combatLoop(Entity killer) { bool usingRange = killer is Player?RangeCombat.isUsingRange(killer) : npcUsesRange(killer); Entity target = killer.getTarget(); killer.incrementCombatTurns(); bool autoCasting = killer is Npc ? false : ((Player)killer).getTemporaryAttribute("autoCasting") != null; bool dragonfire = false; bool guthanSpecial = false; //if you are auto casting you are not in combat loop. if (autoCasting) { return; } //If who you were attacking or who attacked you doesn't exist anymore. [Most important, should be first] if (target == null || (killer.getAttacker() == null && target == null)) { //stop fighting. resetCombat(killer, 1); return; } //If it's the npc attacking and npc isn't owned by a player or player is attacking if ((killer is Npc) && ((Npc)killer).getOwner() == null || killer is Player) { if (killer.getLastAttacked() > 0 || killer.getLastAttack() > 0) { //if the last time npc or player was attacked was 6 seconds ago or last time npc or player attacked was 6 seconds ago if (isXSecondsSinceCombat(killer, killer.getLastAttacked(), 6000) && isXSecondsSinceCombat(killer, killer.getLastAttack(), 6000)) { //stop fighting. resetCombat(killer, 1); return; } } } //If you are a player and using range then your distance is 8 or if you are a npc using range get the npc's attackRange otherwise get the sie of the npc as distance. int distance = (killer is Player && usingRange) ? 8 : killer is Npc && usingRange?getNpcAttackRange(killer) : getNPCSize(killer, target); //if you the player are not using range and you are attacking another player if (!usingRange && killer is Player && target is Player) { //if the player who is getting attacked is not standing still. if (((Player)target).getSprites().getPrimarySprite() != -1) { //if you are using range on a player who is moving then distance to attack is 11, otherwise no range it's 3. distance = usingRange ? 11 : 3; } } //If all[player vs player], [player vs npc] or [npc vs player] are within distance of each other. if (!killer.getLocation().withinDistance(target.getLocation(), distance) && !target.getLocation().withinDistance(killer.getLocation(), distance)) { return; } //Can you [npc or player] even attack the entity if (!canAttack(killer, target, usingRange)) { //stop fighting. resetCombat(killer, 0); return; } //are you [npc or player] using ranged attacks? if (usingRange) { //if you are a player if (killer is Player) { //Do you have ammo and a bow? if (RangeCombat.hasAmmo(killer) && RangeCombat.hasValidBowArrow(killer)) { ((Player)killer).getWalkingQueue().resetWalkingQueue(); ((Player)killer).getPackets().closeInterfaces(); ((Player)killer).getPackets().clearMapFlag(); } else { //You cannot attack the monster as you don't have ammo or a bow. killer.setTarget(null); return; } } } //are you a player who is attacking a npc. if (target is Npc && killer is Player) { //If you are attacking Zilyana boss. if (((Npc)target).getId() == 6247) // Zilyana (sara boss) //TODO: Stop any walking err why only zilyana boss?, have to check this out later. { ((Player)killer).getWalkingQueue().resetWalkingQueue(); ((Player)killer).getPackets().clearMapFlag(); } } //All the checks above are passed, below starts the actual assigning of target and doing the attack. //if you [npc or player] attacking turn is greater or equal to your attacking speed. if (killer.getCombatTurns() >= killer.getAttackSpeed()) { //if [npc or player] has auto attack back on, and who they are attacking still exists. if (target.isAutoRetaliating() && target.getTarget() == null) { //make the [npc or player] follow who they are trying to attack. target.getFollow().setFollowing(killer); //make the [npc or player] face up to their attacker. target.setEntityFocus(killer.getClientIndex()); if ((target.getCombatTurns() >= (target.getAttackSpeed() / 2)) && target.getAttacker() == null) { target.setCombatTurns(target.getAttackSpeed() / 2); } //assign the [npc or player] who is getting attacked it's target who is attacking them. target.setTarget(killer); //if the person who is getting attacked is a player if (target is Player) { //stop the movement of player who is getting attacked ((Player)target).getWalkingQueue().resetWalkingQueue(); ((Player)target).getPackets().clearMapFlag(); } } //set the attack delay, if you are using range then delay is 2.4 seconds, otherwise magic.. 2.75 seconds. int delay = usingRange ? 2400 : 2750; //if delay has come up. if (Environment.TickCount - killer.getLastMagicAttack() < delay) { //If the player who is attacking using range. if (usingRange && killer is Player) { //Stop the movement of the attacker who is using ranged attacks. ((Player)killer).getWalkingQueue().resetWalkingQueue(); ((Player)killer).getPackets().clearMapFlag(); } return; } //if the attacker is a npc if (killer is Npc) { //perform the npc attack as a killer on your target (most likely a player) if (NPCAttack.npcAttack((Npc)killer, target)) { return; //if the dice 50/50 kicks in and the npc attacking is a dragon. } else if ((misc.random(2) == 0) && isDragon(killer)) { //do your dragon fire as a dragon npc. doDragonfire(killer, target); //dragonfire was done, variable used to stop some attack animation. dragonfire = true; } } //If the person getting attacked is a player. if (target is Player) { //Close all your interfaces. ((Player)target).getPackets().closeInterfaces(); } //if the attacker [npc or player] has a attack animation and dragonfire variable wasn't set. if ((killer.getAttackAnimation() != 65535) && !dragonfire) { //do your attack animation as a [npc or player]. killer.setLastAnimation(new Animation(killer.getAttackAnimation())); } //If the [player or npc] is using ranged attacks if (!usingRange) { if (target.getCombatTurns() < 0 || target.getCombatTurns() > 0) { //if the [player or npc] getting attacked has a defensive animation. if (target.getDefenceAnimation() != 65535) { //do a blocking/defensive animation. target.setLastAnimation(new Animation(target.getDefenceAnimation())); } } } //make the attacker [player or npc] start following the attacked. killer.getFollow().setFollowing(target); //set a timer for the [player or npc] which indicates the last time they were attacked by killer. target.setLastAttacked(Environment.TickCount); //set a timer for the [player or npc] which indicates the last time they attacked the target. killer.setLastAttack(Environment.TickCount); //reset the combat turns. [this makes sure both attackers don't attack at same time] killer.resetCombatTurns(); //assign the [npc or player] who is getting attacked it's target who is attacking them. target.setAttacker(killer); //set a skulls, the method checks if [player attacks player] also [checks if player is dueling or in fightpits or has skull], otherwise gets skull. setSkull(killer, target); //if the attacker is a player. if (killer is Player) { //set attacking player's combatType to melee attack. ((Player)killer).setLastCombatType(CombatType.MELEE); //close all your interfaces as a attacker ((Player)killer).getPackets().closeInterfaces(); //if you the attacking player is using a special attack. if (((Player)killer).getSpecialAttack().isUsingSpecial()) { //do your special attack on your target which may be a [player or npc] if (((Player)killer).getSpecialAttack().doSpecialAttack(killer, target)) { return; } //if you the attacking player is wearing guthan armour set. } else if (CombatFormula.wearingGuthan((Player)killer)) { //roll a 25% dice. if (misc.random(4) == 0) { //if dice hits 25%, show some kind of graphics.. killer.setLastGraphics(new Graphics(398, 0)); //set some variable to indicate you are using guthan special. guthanSpecial = true; } } } //if you the [player or npc] is using range. if (usingRange) { //Go into the RangeCombat ranging logic loop processing class. RangeCombat.rangeCombatLoop(killer, target); return; } //if the dragon npc did his dragonfire attack quit right here. if (dragonfire) { return; } //copies guthanSpecial variable to a different variable so it won't change when passed into a Event. bool guthanSpec = guthanSpecial; //get the damage you as the attacker [player or npc] will do on target [player or npc] double damage = getDamage(killer, target); //checks if damage will kill the player, sets a temporary variable 'willDie' checkIfWillDie(target, damage); //trigger the attack event based on the attackers [player or npc] hit delay Event attackEvent = new Event(killer.getHitDelay()); attackEvent.setAction(() => { //stop attack event after this run attackEvent.stop(); //add the XP for the killer [player only]. addXp(killer, target, damage); //set the hit to be sent on the attacked target [player or npc] target.hit((int)damage); //if the attacker [player] is using the Smite prayer drain prayer from target [player] based on damage done checkSmite(killer, target, damage); //if the attack [pla checkRecoil(killer, target, damage); checkVengeance(killer, target, damage); //if you are using the guthanSpecial which does some healing if (guthanSpec) { // heals 30% of the damage, and an added random 70% of the damage killer.heal((int)(damage * 0.30 + (misc.randomDouble() * (damage * 0.70)))); } //if the target you are attacking is a npc. if (target is Npc) { //if it is Tzhaar monsters, you as the attacker will take 1 damage. if (((Npc)target).getId() == 2736 || ((Npc)target).getId() == 2737) // Tzhaar lvl 45s { killer.hit(1); // their recoil attack } } }); Server.registerEvent(attackEvent); } }
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); } }