Example #1
0
        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       = CombatFormula.getMagicHit(p, target, getSpellMaxHit(p, index));
            bool   magicProtect = false;

            if (target is Player)
            {
                magicProtect = ((Player)target).getPrayers().getHeadIcon() == PrayerData.PrayerHeadIcon.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.isVisible() || 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.checkRecoilRing(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(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(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 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);
            double damage1     = misc.randomDouble(getDamage((Player)killer, target, usingBow, usingArrows));
            double damage2     = usingBow == DARK_BOW?misc.randomDouble(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() - (int)damage1;
                if (damage2 > hpRemaining)
                {
                    damage2 = hpRemaining;
                }
            }
            double totalDamage = damage1 + damage2;

            Combat.checkIfWillDie(target, (damage1 + damage2));
            Event doRangedAttackEvent = new Event(hitDelay);

            doRangedAttackEvent.setAction(() => {
                double 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.checkRecoilRing(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 void setLastCombatType(Combat.CombatType lastCombatType)
 {
     this.lastCombatType = lastCombatType;
 }