Search in sources :

Example 6 with MapleStatEffect

use of server.MapleStatEffect in project HeavenMS by ronancpl.

the class RangedAttackHandler method handlePacket.

@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    MapleCharacter chr = c.getPlayer();
    chr.setPetLootCd(System.currentTimeMillis());
    /*long timeElapsed = System.currentTimeMillis() - chr.getAutobanManager().getLastSpam(8);
        if(timeElapsed < 300) {
            AutobanFactory.FAST_ATTACK.alert(chr, "Time: " + timeElapsed);
        }
        chr.getAutobanManager().spam(8);*/
    AttackInfo attack = parseDamage(slea, chr, true, false);
    if (chr.getBuffEffect(MapleBuffStat.MORPH) != null) {
        if (chr.getBuffEffect(MapleBuffStat.MORPH).isMorphWithoutAttack()) {
            // How are they attacking when the client won't let them?
            chr.getClient().disconnect(false, false);
            return;
        }
    }
    if (chr.getMap().isDojoMap() && attack.numAttacked > 0) {
        chr.setDojoEnergy(chr.getDojoEnergy() + ServerConstants.DOJO_ENERGY_ATK);
        c.announce(MaplePacketCreator.getEnergy("energy", chr.getDojoEnergy()));
    }
    if (attack.skill == Buccaneer.ENERGY_ORB || attack.skill == ThunderBreaker.SPARK || attack.skill == Shadower.TAUNT || attack.skill == NightLord.TAUNT) {
        chr.getMap().broadcastMessage(chr, MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false);
        applyAttack(attack, chr, 1);
    } else if (attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.COMBO_FENRIR || attack.skill == Aran.COMBO_TEMPEST) {
        chr.getMap().broadcastMessage(chr, MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false);
        if (attack.skill == Aran.COMBO_SMASH && chr.getCombo() >= 30) {
            chr.setCombo((short) 0);
            applyAttack(attack, chr, 1);
        } else if (attack.skill == Aran.COMBO_FENRIR && chr.getCombo() >= 100) {
            chr.setCombo((short) 0);
            applyAttack(attack, chr, 2);
        } else if (attack.skill == Aran.COMBO_TEMPEST && chr.getCombo() >= 200) {
            chr.setCombo((short) 0);
            applyAttack(attack, chr, 4);
        }
    } else {
        Item weapon = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11);
        MapleWeaponType type = MapleItemInformationProvider.getInstance().getWeaponType(weapon.getItemId());
        if (type == MapleWeaponType.NOT_A_WEAPON) {
            return;
        }
        short slot = -1;
        int projectile = 0;
        byte bulletCount = 1;
        MapleStatEffect effect = null;
        if (attack.skill != 0) {
            effect = attack.getAttackEffect(chr, null);
            bulletCount = effect.getBulletCount();
            if (effect.getCooldown() > 0) {
                c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect.getCooldown()));
            }
        }
        boolean hasShadowPartner = chr.getBuffedValue(MapleBuffStat.SHADOWPARTNER) != null;
        if (hasShadowPartner) {
            bulletCount *= 2;
        }
        MapleInventory inv = chr.getInventory(MapleInventoryType.USE);
        for (short i = 1; i <= inv.getSlotLimit(); i++) {
            Item item = inv.getItem(i);
            if (item != null) {
                int id = item.getItemId();
                slot = item.getPosition();
                boolean bow = ItemConstants.isArrowForBow(id);
                boolean cbow = ItemConstants.isArrowForCrossBow(id);
                if (item.getQuantity() >= bulletCount) {
                    // Fixes the bug where you can't use your last arrow.
                    if (type == MapleWeaponType.CLAW && ItemConstants.isThrowingStar(id) && weapon.getItemId() != 1472063) {
                        if (((id == 2070007 || id == 2070018) && chr.getLevel() < 70) || (id == 2070016 && chr.getLevel() < 50)) {
                        } else {
                            projectile = id;
                            break;
                        }
                    } else if ((type == MapleWeaponType.GUN && ItemConstants.isBullet(id))) {
                        if (id == 2331000 && id == 2332000) {
                            if (chr.getLevel() > 69) {
                                projectile = id;
                                break;
                            }
                        } else if (chr.getLevel() > (id % 10) * 20 + 9) {
                            projectile = id;
                            break;
                        }
                    } else if ((type == MapleWeaponType.BOW && bow) || (type == MapleWeaponType.CROSSBOW && cbow) || (weapon.getItemId() == 1472063 && (bow || cbow))) {
                        projectile = id;
                        break;
                    }
                }
            }
        }
        boolean soulArrow = chr.getBuffedValue(MapleBuffStat.SOULARROW) != null;
        boolean shadowClaw = chr.getBuffedValue(MapleBuffStat.SHADOW_CLAW) != null;
        if (projectile != 0) {
            if (!soulArrow && !shadowClaw && attack.skill != 11101004 && attack.skill != 15111007 && attack.skill != 14101006) {
                byte bulletConsume = bulletCount;
                if (effect != null && effect.getBulletConsume() != 0) {
                    bulletConsume = (byte) (effect.getBulletConsume() * (hasShadowPartner ? 2 : 1));
                }
                if (slot < 0)
                    System.out.println("<ERROR> Projectile to use was unable to be found.");
                else
                    MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, bulletConsume, false, true);
            }
        }
        if (projectile != 0 || soulArrow || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) {
            // visible projectile sent to players
            int visProjectile = projectile;
            if (ItemConstants.isThrowingStar(projectile)) {
                MapleInventory cash = chr.getInventory(MapleInventoryType.CASH);
                for (int i = 1; i <= cash.getSlotLimit(); i++) {
                    // impose order...
                    Item item = cash.getItem((short) i);
                    if (item != null) {
                        if (item.getItemId() / 1000 == 5021) {
                            visProjectile = item.getItemId();
                            break;
                        }
                    }
                }
            } else // bow, crossbow
            if (soulArrow || attack.skill == 3111004 || attack.skill == 3211004 || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) {
                visProjectile = 0;
            }
            byte[] packet;
            switch(attack.skill) {
                // Hurricane
                case 3121004:
                // Pierce
                case 3221001:
                // Rapid Fire
                case 5221004:
                case // KoC Hurricane
                13111002:
                    packet = MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.rangedirection, attack.numAttackedAndDamage, visProjectile, attack.allDamage, attack.speed, attack.direction, attack.display);
                    break;
                default:
                    packet = MaplePacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, visProjectile, attack.allDamage, attack.speed, attack.direction, attack.display);
                    break;
            }
            chr.getMap().broadcastMessage(chr, packet, false, true);
            if (effect != null) {
                int money = effect.getMoneyCon();
                if (money != 0) {
                    int moneyMod = money / 2;
                    money += Randomizer.nextInt(moneyMod);
                    if (money > chr.getMeso()) {
                        money = chr.getMeso();
                    }
                    chr.gainMeso(-money, false);
                }
            }
            if (attack.skill != 0) {
                Skill skill = SkillFactory.getSkill(attack.skill);
                MapleStatEffect effect_ = skill.getEffect(chr.getSkillLevel(skill));
                if (effect_.getCooldown() > 0) {
                    if (chr.skillIsCooling(attack.skill)) {
                        return;
                    } else {
                        c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
                        chr.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
                    }
                }
            }
            if (chr.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 && chr.getBuffedValue(MapleBuffStat.DARKSIGHT) != null && attack.numAttacked > 0 && chr.getBuffSource(MapleBuffStat.DARKSIGHT) != 9101004) {
                chr.cancelEffectFromBuffStat(MapleBuffStat.DARKSIGHT);
                chr.cancelBuffStats(MapleBuffStat.DARKSIGHT);
            } else if (chr.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 && chr.getBuffedValue(MapleBuffStat.WIND_WALK) != null && attack.numAttacked > 0) {
                chr.cancelEffectFromBuffStat(MapleBuffStat.WIND_WALK);
                chr.cancelBuffStats(MapleBuffStat.WIND_WALK);
            }
            applyAttack(attack, chr, bulletCount);
        }
    }
}
Also used : Item(client.inventory.Item) MapleCharacter(client.MapleCharacter) Skill(client.Skill) MapleWeaponType(client.inventory.MapleWeaponType) MapleStatEffect(server.MapleStatEffect) MapleInventory(client.inventory.MapleInventory)

Example 7 with MapleStatEffect

use of server.MapleStatEffect in project HeavenMS by ronancpl.

the class PetAutoPotHandler method handlePacket.

@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
    if (!c.getPlayer().isAlive()) {
        c.announce(MaplePacketCreator.enableActions());
        return;
    }
    slea.readByte();
    slea.readLong();
    slea.readInt();
    slot = slea.readShort();
    itemId = slea.readInt();
    MapleCharacter chr = c.getPlayer();
    toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);
    if (toUse != null) {
        if (toUse.getItemId() != itemId) {
            c.announce(MaplePacketCreator.enableActions());
            return;
        }
        toUseList = null;
        // from now on, toUse becomes the "cursor" for the current pot being used
        if (toUse.getQuantity() <= 0) {
            if (!cursorOnNextAvailablePot(chr)) {
                c.announce(MaplePacketCreator.enableActions());
                return;
            }
        }
        MapleStatEffect stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
        hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
        hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
        // contabilize the HP and MP gains from equipments on one's effective MaxHP/MaxMP
        Pair<Short, Short> maxHpMp = calcEffectivePool(chr);
        maxHp = maxHpMp.left;
        maxMp = maxHpMp.right;
        incHp = stat.getHp();
        if (incHp <= 0 && hasHpGain)
            incHp = (short) ((maxHp * stat.getHpRate()) / 100.0);
        incMp = stat.getMp();
        if (incMp <= 0 && hasMpGain)
            incMp = (short) ((maxMp * stat.getMpRate()) / 100.0);
        curHp = chr.getHp();
        curMp = chr.getMp();
        // System.out.println("\n-------------------\n");
        while (true) {
            do {
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
                stat.applyTo(chr);
                curHp += incHp;
                curMp += incMp;
            // System.out.println();
            // System.out.println("hp: " + hasHpGain + " player hp " + curHp + " maxhp " + maxHp);
            // System.out.println("mp: " + hasMpGain + " player mp " + curMp + " maxmp " + maxMp);
            // System.out.println("redo? " + (shouldReusePot(chr) && toUse.getQuantity() > 0));
            } while (shouldReusePot(chr) && toUse.getQuantity() > 0);
            if (toUse.getQuantity() == 0 && shouldReusePot(chr)) {
                if (!cursorOnNextAvailablePot(chr)) {
                    // no more pots available
                    break;
                }
            } else {
                // gracefully finished it's job, quit the loop
                break;
            }
        }
    }
}
Also used : MapleCharacter(client.MapleCharacter) MapleStatEffect(server.MapleStatEffect)

Example 8 with MapleStatEffect

use of server.MapleStatEffect in project HeavenMS by ronancpl.

the class MapleMap method addPlayer.

public void addPlayer(final MapleCharacter chr) {
    int chrSize;
    chrWLock.lock();
    try {
        characters.add(chr);
        chrSize = characters.size();
        addPartyMemberInternal(chr);
    } finally {
        chrWLock.unlock();
    }
    chr.setMapId(mapid);
    itemMonitorTimeout = 1;
    if (chrSize == 1) {
        if (!hasItemMonitor())
            startItemMonitor();
        if (onFirstUserEnter.length() != 0 && !chr.hasEntered(onFirstUserEnter, mapid) && MapScriptManager.getInstance().scriptExists(onFirstUserEnter, true)) {
            chr.enteredScript(onFirstUserEnter, mapid);
            MapScriptManager.getInstance().getMapScript(chr.getClient(), onFirstUserEnter, true);
        }
    }
    if (onUserEnter.length() != 0) {
        if (onUserEnter.equals("cygnusTest") && (mapid < 913040000 || mapid > 913040006)) {
            chr.saveLocation("INTRO");
        }
        MapScriptManager.getInstance().getMapScript(chr.getClient(), onUserEnter, false);
    }
    if (FieldLimit.CANNOTUSEMOUNTS.check(fieldLimit) && chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING) != null) {
        chr.cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
        chr.cancelBuffStats(MapleBuffStat.MONSTER_RIDING);
    }
    if (mapid == 923010000 && getMonsterById(9300102) == null) {
        // Kenta's Mount Quest
        spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(9300102), new Point(77, 426));
    } else if (mapid == 200090060) {
        // To Rien
        chr.announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090060) {
                    chr.changeMap(140020300, 0);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 200090070) {
        // To Lith Harbor
        chr.announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090070) {
                    chr.changeMap(104000000, 3);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 200090030) {
        // To Ereve (SkyFerry)
        chr.getClient().announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090030) {
                    chr.changeMap(130000210, 0);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 200090031) {
        // To Victoria Island (SkyFerry)
        chr.getClient().announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090031) {
                    chr.changeMap(101000400, 0);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 200090021) {
        // To Orbis (SkyFerry)
        chr.getClient().announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090021) {
                    chr.changeMap(200000161, 0);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 200090020) {
        // To Ereve From Orbis (SkyFerry)
        chr.getClient().announce(MaplePacketCreator.getClock(60));
        TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                if (chr.getMapId() == 200090020) {
                    chr.changeMap(130000210, 0);
                }
            }
        }, 60 * 1000);
    } else if (mapid == 103040400) {
        if (chr.getEventInstance() != null) {
            chr.getEventInstance().movePlayer(chr);
        }
    } else if (MapleMiniDungeonInfo.isDungeonMap(mapid)) {
        MapleMiniDungeon mmd = chr.getClient().getChannelServer().getMiniDungeon(mapid);
        if (mmd != null)
            mmd.registerPlayer(chr);
    }
    MaplePet[] pets = chr.getPets();
    for (int i = 0; i < pets.length; i++) {
        if (pets[i] != null) {
            pets[i].setPos(getGroundBelow(chr.getPosition()));
            chr.announce(MaplePacketCreator.showPet(chr, pets[i], false, false));
        } else {
            break;
        }
    }
    if (chr.isHidden()) {
        broadcastGMMessage(chr, MaplePacketCreator.spawnPlayerMapObject(chr), false);
        chr.announce(MaplePacketCreator.getGMEffect(0x10, (byte) 1));
        List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
        broadcastGMMessage(chr, MaplePacketCreator.giveForeignBuff(chr.getId(), dsstat), false);
    } else {
        broadcastMessage(chr, MaplePacketCreator.spawnPlayerMapObject(chr), false);
    }
    sendObjectPlacement(chr.getClient());
    if (isStartingEventMap() && !eventStarted()) {
        chr.getMap().getPortal("join00").setPortalStatus(false);
    }
    if (hasForcedEquip()) {
        chr.getClient().announce(MaplePacketCreator.showForcedEquip(-1));
    }
    if (specialEquip()) {
        chr.getClient().announce(MaplePacketCreator.coconutScore(0, 0));
        chr.getClient().announce(MaplePacketCreator.showForcedEquip(chr.getTeam()));
    }
    objectWLock.lock();
    try {
        this.mapobjects.put(Integer.valueOf(chr.getObjectId()), chr);
    } finally {
        objectWLock.unlock();
    }
    if (chr.getPlayerShop() != null) {
        addMapObject(chr.getPlayerShop());
    }
    final MapleDragon dragon = chr.getDragon();
    if (dragon != null) {
        dragon.setPosition(chr.getPosition());
        this.addMapObject(dragon);
        if (chr.isHidden()) {
            this.broadcastGMMessage(chr, MaplePacketCreator.spawnDragon(dragon));
        } else {
            this.broadcastMessage(chr, MaplePacketCreator.spawnDragon(dragon));
        }
    }
    MapleStatEffect summonStat = chr.getStatForBuff(MapleBuffStat.SUMMON);
    if (summonStat != null) {
        MapleSummon summon = chr.getSummonByKey(summonStat.getSourceId());
        summon.setPosition(chr.getPosition());
        chr.getMap().spawnSummon(summon);
        updateMapObjectVisibility(chr, summon);
    }
    if (mapEffect != null) {
        mapEffect.sendStartData(chr.getClient());
    }
    chr.getClient().announce(MaplePacketCreator.resetForcedStats());
    if (mapid == 914000200 || mapid == 914000210 || mapid == 914000220) {
        chr.getClient().announce(MaplePacketCreator.aranGodlyStats());
    }
    if (chr.getEventInstance() != null && chr.getEventInstance().isTimerStarted()) {
        chr.getClient().announce(MaplePacketCreator.getClock((int) (chr.getEventInstance().getTimeLeft() / 1000)));
    }
    if (chr.getFitness() != null && chr.getFitness().isTimerStarted()) {
        chr.getClient().announce(MaplePacketCreator.getClock((int) (chr.getFitness().getTimeLeft() / 1000)));
    }
    if (chr.getOla() != null && chr.getOla().isTimerStarted()) {
        chr.getClient().announce(MaplePacketCreator.getClock((int) (chr.getOla().getTimeLeft() / 1000)));
    }
    if (mapid == 109060000) {
        chr.announce(MaplePacketCreator.rollSnowBall(true, 0, null, null));
    }
    MonsterCarnival carnival = chr.getCarnival();
    MonsterCarnivalParty cparty = chr.getCarnivalParty();
    if (carnival != null && cparty != null && (mapid == 980000101 || mapid == 980000201 || mapid == 980000301 || mapid == 980000401 || mapid == 980000501 || mapid == 980000601)) {
        chr.getClient().announce(MaplePacketCreator.getClock((int) (carnival.getTimeLeft() / 1000)));
        chr.getClient().announce(MaplePacketCreator.startCPQ(chr, carnival.oppositeTeam(cparty)));
    }
    if (hasClock()) {
        Calendar cal = Calendar.getInstance();
        chr.getClient().announce((MaplePacketCreator.getClockTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND))));
    }
    if (hasBoat() > 0) {
        if (hasBoat() == 1)
            chr.getClient().announce((MaplePacketCreator.boatPacket(true)));
        else
            chr.getClient().announce(MaplePacketCreator.boatPacket(false));
    }
    chr.receivePartyMemberHP();
}
Also used : MapleBuffStat(client.MapleBuffStat) MonsterCarnival(server.partyquest.MonsterCarnival) Calendar(java.util.Calendar) MonsterCarnivalParty(server.partyquest.MonsterCarnivalParty) Point(java.awt.Point) SpawnPoint(server.life.SpawnPoint) Point(java.awt.Point) SpawnPoint(server.life.SpawnPoint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MapleStatEffect(server.MapleStatEffect) MaplePet(client.inventory.MaplePet) Pair(tools.Pair)

Example 9 with MapleStatEffect

use of server.MapleStatEffect in project HeavenMS by ronancpl.

the class AbstractDealDamageHandler method parseDamage.

protected AttackInfo parseDamage(LittleEndianAccessor lea, MapleCharacter chr, boolean ranged, boolean magic) {
    // 2C 00 00 01 91 A1 12 00 A5 57 62 FC E2 75 99 10 00 47 80 01 04 01 C6 CC 02 DD FF 5F 00
    AttackInfo ret = new AttackInfo();
    lea.readByte();
    ret.numAttackedAndDamage = lea.readByte();
    ret.numAttacked = (ret.numAttackedAndDamage >>> 4) & 0xF;
    ret.numDamage = ret.numAttackedAndDamage & 0xF;
    ret.allDamage = new HashMap<>();
    ret.skill = lea.readInt();
    ret.ranged = ranged;
    ret.magic = magic;
    if (ret.skill > 0) {
        ret.skilllevel = chr.getSkillLevel(ret.skill);
        if (ret.skilllevel == 0 && GameConstants.isPqSkillMap(chr.getMapId()) && GameConstants.isPqSkill(ret.skill))
            ret.skilllevel = 1;
    }
    if (ret.skill == Evan.ICE_BREATH || ret.skill == Evan.FIRE_BREATH || ret.skill == FPArchMage.BIG_BANG || ret.skill == ILArchMage.BIG_BANG || ret.skill == Bishop.BIG_BANG || ret.skill == Gunslinger.GRENADE || ret.skill == Brawler.CORKSCREW_BLOW || ret.skill == ThunderBreaker.CORKSCREW_BLOW || ret.skill == NightWalker.POISON_BOMB) {
        ret.charge = lea.readInt();
    } else {
        ret.charge = 0;
    }
    if (ret.skill == Paladin.HEAVENS_HAMMER) {
        ret.isHH = true;
    } else if (ret.skill == Aran.COMBO_TEMPEST) {
        ret.isTempest = true;
    }
    lea.skip(8);
    ret.display = lea.readByte();
    ret.direction = lea.readByte();
    ret.stance = lea.readByte();
    if (ret.skill == ChiefBandit.MESO_EXPLOSION) {
        if (ret.numAttackedAndDamage == 0) {
            lea.skip(10);
            int bullets = lea.readByte();
            for (int j = 0; j < bullets; j++) {
                int mesoid = lea.readInt();
                lea.skip(1);
                ret.allDamage.put(Integer.valueOf(mesoid), null);
            }
            return ret;
        } else {
            lea.skip(6);
        }
        for (int i = 0; i < ret.numAttacked + 1; i++) {
            int oid = lea.readInt();
            if (i < ret.numAttacked) {
                lea.skip(12);
                int bullets = lea.readByte();
                List<Integer> allDamageNumbers = new ArrayList<>();
                for (int j = 0; j < bullets; j++) {
                    int damage = lea.readInt();
                    allDamageNumbers.add(Integer.valueOf(damage));
                }
                ret.allDamage.put(Integer.valueOf(oid), allDamageNumbers);
                lea.skip(4);
            } else {
                int bullets = lea.readByte();
                for (int j = 0; j < bullets; j++) {
                    int mesoid = lea.readInt();
                    lea.skip(1);
                    ret.allDamage.put(Integer.valueOf(mesoid), null);
                }
            }
        }
        return ret;
    }
    if (ranged) {
        lea.readByte();
        ret.speed = lea.readByte();
        lea.readByte();
        ret.rangedirection = lea.readByte();
        lea.skip(7);
        if (ret.skill == Bowmaster.HURRICANE || ret.skill == Marksman.PIERCING_ARROW || ret.skill == Corsair.RAPID_FIRE || ret.skill == WindArcher.HURRICANE) {
            lea.skip(4);
        }
    } else {
        lea.readByte();
        ret.speed = lea.readByte();
        lea.skip(4);
    }
    // Find the base damage to base futher calculations on.
    // Several skills have their own formula in this section.
    int calcDmgMax = 0;
    if (magic && ret.skill != 0) {
        calcDmgMax = (chr.getTotalMagic() * chr.getTotalMagic() / 1000 + chr.getTotalMagic()) / 30 + chr.getTotalInt() / 200;
    } else if (ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) {
        calcDmgMax = (chr.getTotalLuk() * 5) * chr.getTotalWatk() / 100;
    } else if (ret.skill == DragonKnight.DRAGON_ROAR) {
        calcDmgMax = (chr.getTotalStr() * 4 + chr.getTotalDex()) * chr.getTotalWatk() / 100;
    } else if (ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) {
        calcDmgMax = (int) (18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100 * chr.calculateMaxBaseDamage(chr.getTotalWatk());
    } else {
        calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk());
    }
    if (ret.skill != 0) {
        Skill skill = SkillFactory.getSkill(ret.skill);
        MapleStatEffect effect = skill.getEffect(ret.skilllevel);
        if (magic) {
            // Since the skill is magic based, use the magic formula
            if (chr.getJob() == MapleJob.IL_ARCHMAGE || chr.getJob() == MapleJob.IL_MAGE) {
                int skillLvl = chr.getSkillLevel(ILMage.ELEMENT_AMPLIFICATION);
                if (skillLvl > 0)
                    calcDmgMax = calcDmgMax * SkillFactory.getSkill(ILMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
            } else if (chr.getJob() == MapleJob.FP_ARCHMAGE || chr.getJob() == MapleJob.FP_MAGE) {
                int skillLvl = chr.getSkillLevel(FPMage.ELEMENT_AMPLIFICATION);
                if (skillLvl > 0)
                    calcDmgMax = calcDmgMax * SkillFactory.getSkill(FPMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
            } else if (chr.getJob() == MapleJob.BLAZEWIZARD3 || chr.getJob() == MapleJob.BLAZEWIZARD4) {
                int skillLvl = chr.getSkillLevel(BlazeWizard.ELEMENT_AMPLIFICATION);
                if (skillLvl > 0)
                    calcDmgMax = calcDmgMax * SkillFactory.getSkill(BlazeWizard.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
            } else if (chr.getJob() == MapleJob.EVAN7 || chr.getJob() == MapleJob.EVAN8 || chr.getJob() == MapleJob.EVAN9 || chr.getJob() == MapleJob.EVAN10) {
                int skillLvl = chr.getSkillLevel(Evan.MAGIC_AMPLIFICATION);
                if (skillLvl > 0)
                    calcDmgMax = calcDmgMax * SkillFactory.getSkill(Evan.MAGIC_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
            }
            calcDmgMax *= effect.getMatk();
            if (ret.skill == Cleric.HEAL) {
                // This formula is still a bit wonky, but it is fairly accurate.
                calcDmgMax = (int) Math.round((chr.getTotalInt() * 4.8 + chr.getTotalLuk() * 4) * chr.getTotalMagic() / 1000);
                calcDmgMax = calcDmgMax * effect.getHp() / 100;
            }
        } else if (ret.skill == Hermit.SHADOW_MESO) {
            // Shadow Meso also has its own formula
            calcDmgMax = effect.getMoneyCon() * 10;
            calcDmgMax = (int) Math.floor(calcDmgMax * 1.5);
        } else {
            // Normal damage formula for skills
            calcDmgMax = calcDmgMax * effect.getDamage() / 100;
        }
    }
    Integer comboBuff = chr.getBuffedValue(MapleBuffStat.COMBO);
    if (comboBuff != null && comboBuff > 0) {
        int oid = chr.isCygnus() ? DawnWarrior.COMBO : Crusader.COMBO;
        int advcomboid = chr.isCygnus() ? DawnWarrior.ADVANCED_COMBO : Hero.ADVANCED_COMBO;
        if (comboBuff > 6) {
            // Advanced Combo
            MapleStatEffect ceffect = SkillFactory.getSkill(advcomboid).getEffect(chr.getSkillLevel(advcomboid));
            calcDmgMax = (int) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + 0.20 + (comboBuff - 5) * 0.04);
        } else {
            // Normal Combo
            int skillLv = chr.getSkillLevel(oid);
            if (skillLv <= 0 || chr.isGM())
                skillLv = SkillFactory.getSkill(oid).getMaxLevel();
            if (skillLv > 0) {
                MapleStatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv);
                calcDmgMax = (int) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + Math.floor((comboBuff - 1) * (skillLv / 6)) / 100);
            }
        }
        if (GameConstants.isFinisherSkill(ret.skill)) {
            // Finisher skills do more damage based on how many orbs the player has.
            int orbs = comboBuff - 1;
            if (orbs == 2)
                calcDmgMax *= 1.2;
            else if (orbs == 3)
                calcDmgMax *= 1.54;
            else if (orbs == 4)
                calcDmgMax *= 2;
            else if (orbs >= 5)
                calcDmgMax *= 2.5;
        }
    }
    if (chr.getEnergyBar() == 15000) {
        int energycharge = chr.isCygnus() ? ThunderBreaker.ENERGY_CHARGE : Marauder.ENERGY_CHARGE;
        MapleStatEffect ceffect = SkillFactory.getSkill(energycharge).getEffect(chr.getSkillLevel(energycharge));
        calcDmgMax *= ceffect.getDamage() / 100;
    }
    if (chr.getMapId() >= 914000000 && chr.getMapId() <= 914000500) {
        // Aran Tutorial.
        calcDmgMax += 80000;
    }
    boolean canCrit = false;
    if (chr.getJob().isA((MapleJob.BOWMAN)) || chr.getJob().isA(MapleJob.THIEF) || chr.getJob().isA(MapleJob.NIGHTWALKER1) || chr.getJob().isA(MapleJob.WINDARCHER1) || chr.getJob() == MapleJob.ARAN3 || chr.getJob() == MapleJob.ARAN4 || chr.getJob() == MapleJob.MARAUDER || chr.getJob() == MapleJob.BUCCANEER) {
        canCrit = true;
    }
    if (chr.getBuffEffect(MapleBuffStat.SHARP_EYES) != null) {
        // Any class that has sharp eyes can crit. Also, since it stacks with normal crit go ahead
        // and calc it in.
        canCrit = true;
        calcDmgMax *= 1.4;
    }
    boolean shadowPartner = false;
    if (chr.getBuffEffect(MapleBuffStat.SHADOWPARTNER) != null) {
        shadowPartner = true;
    }
    if (ret.skill != 0) {
        int fixed = ret.getAttackEffect(chr, SkillFactory.getSkill(ret.skill)).getFixDamage();
        if (fixed > 0)
            calcDmgMax = fixed;
    }
    for (int i = 0; i < ret.numAttacked; i++) {
        int oid = lea.readInt();
        lea.skip(14);
        List<Integer> allDamageNumbers = new ArrayList<>();
        MapleMonster monster = chr.getMap().getMonsterByOid(oid);
        if (chr.getBuffEffect(MapleBuffStat.WK_CHARGE) != null) {
            // Charge, so now we need to check elemental effectiveness
            int sourceID = chr.getBuffSource(MapleBuffStat.WK_CHARGE);
            int level = chr.getBuffedValue(MapleBuffStat.WK_CHARGE);
            if (monster != null) {
                if (sourceID == WhiteKnight.BW_FIRE_CHARGE || sourceID == WhiteKnight.SWORD_FIRE_CHARGE) {
                    if (monster.getStats().getEffectiveness(Element.FIRE) == ElementalEffectiveness.WEAK) {
                        calcDmgMax *= 1.05 + level * 0.015;
                    }
                } else if (sourceID == WhiteKnight.BW_ICE_CHARGE || sourceID == WhiteKnight.SWORD_ICE_CHARGE) {
                    if (monster.getStats().getEffectiveness(Element.ICE) == ElementalEffectiveness.WEAK) {
                        calcDmgMax *= 1.05 + level * 0.015;
                    }
                } else if (sourceID == WhiteKnight.BW_LIT_CHARGE || sourceID == WhiteKnight.SWORD_LIT_CHARGE) {
                    if (monster.getStats().getEffectiveness(Element.LIGHTING) == ElementalEffectiveness.WEAK) {
                        calcDmgMax *= 1.05 + level * 0.015;
                    }
                } else if (sourceID == Paladin.BW_HOLY_CHARGE || sourceID == Paladin.SWORD_HOLY_CHARGE) {
                    if (monster.getStats().getEffectiveness(Element.HOLY) == ElementalEffectiveness.WEAK) {
                        calcDmgMax *= 1.2 + level * 0.015;
                    }
                }
            } else {
                // Since we already know the skill has an elemental attribute, but we dont know if the monster is weak or not, lets
                // take the safe approach and just assume they are weak.
                calcDmgMax *= 1.5;
            }
        }
        if (ret.skill != 0) {
            Skill skill = SkillFactory.getSkill(ret.skill);
            if (skill.getElement() != Element.NEUTRAL && chr.getBuffedValue(MapleBuffStat.ELEMENTAL_RESET) == null) {
                // The skill has an element effect, so we need to factor that in.
                if (monster != null) {
                    ElementalEffectiveness eff = monster.getElementalEffectiveness(skill.getElement());
                    if (eff == ElementalEffectiveness.WEAK) {
                        calcDmgMax *= 1.5;
                    } else if (eff == ElementalEffectiveness.STRONG) {
                    // calcDmgMax *= 0.5;
                    }
                } else {
                    // Since we already know the skill has an elemental attribute, but we dont know if the monster is weak or not, lets
                    // take the safe approach and just assume they are weak.
                    calcDmgMax *= 1.5;
                }
            }
            if (ret.skill == FPWizard.POISON_BREATH || ret.skill == FPMage.POISON_MIST || ret.skill == FPArchMage.FIRE_DEMON || ret.skill == ILArchMage.ICE_DEMON) {
                if (monster != null) {
                // Turns out poison is completely server side, so I don't know why I added this. >.<
                // calcDmgMax = monster.getHp() / (70 - chr.getSkillLevel(skill));
                }
            } else if (ret.skill == Hermit.SHADOW_WEB) {
                if (monster != null) {
                    calcDmgMax = monster.getHp() / (50 - chr.getSkillLevel(skill));
                }
            }
        }
        for (int j = 0; j < ret.numDamage; j++) {
            int damage = lea.readInt();
            int hitDmgMax = calcDmgMax;
            if (ret.skill == Buccaneer.BARRAGE) {
                if (j > 3)
                    hitDmgMax *= Math.pow(2, (j - 3));
            }
            if (shadowPartner) {
                // in for the crit effects.
                if (j >= ret.numDamage / 2) {
                    hitDmgMax *= 0.5;
                }
            }
            if (ret.skill == Marksman.SNIPE) {
                damage = 195000 + Randomizer.nextInt(5000);
                hitDmgMax = 200000;
            }
            int maxWithCrit = hitDmgMax;
            if (// They can crit, so up the max.
            canCrit)
                maxWithCrit *= 2;
            // Warn if the damage is over 1.5x what we calculated above.
            if (damage > maxWithCrit * 1.5) {
                AutobanFactory.DAMAGE_HACK.alert(chr, "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")");
            }
            // Add a ab point if its over 5x what we calculated.
            if (damage > maxWithCrit * 5) {
                AutobanFactory.DAMAGE_HACK.addPoint(chr.getAutobanManager(), "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")");
            }
            if (ret.skill == Marksman.SNIPE || (canCrit && damage > hitDmgMax)) {
                // If the skill is a crit, inverse the damage to make it show up on clients.
                damage = -Integer.MAX_VALUE + damage - 1;
            }
            allDamageNumbers.add(damage);
        }
        if (ret.skill != Corsair.RAPID_FIRE || ret.skill != Aran.HIDDEN_FULL_DOUBLE || ret.skill != Aran.HIDDEN_FULL_TRIPLE || ret.skill != Aran.HIDDEN_OVER_DOUBLE || ret.skill != Aran.HIDDEN_OVER_TRIPLE) {
            lea.skip(4);
        }
        ret.allDamage.put(Integer.valueOf(oid), allDamageNumbers);
    }
    if (ret.skill == NightWalker.POISON_BOMB) {
        // Poison Bomb
        lea.skip(4);
        ret.position.setLocation(lea.readShort(), lea.readShort());
    }
    return ret;
}
Also used : Skill(client.Skill) MobSkill(server.life.MobSkill) MapleStatEffect(server.MapleStatEffect) ArrayList(java.util.ArrayList) ElementalEffectiveness(server.life.ElementalEffectiveness) Point(java.awt.Point) MapleMonster(server.life.MapleMonster)

Example 10 with MapleStatEffect

use of server.MapleStatEffect in project HeavenMS by ronancpl.

the class AbstractDealDamageHandler method applyAttack.

protected synchronized void applyAttack(AttackInfo attack, final MapleCharacter player, int attackCount) {
    Skill theSkill = null;
    MapleStatEffect attackEffect = null;
    final int job = player.getJob().getId();
    try {
        if (player.isBanned()) {
            return;
        }
        if (attack.skill != 0) {
            // returns back the skill id if its not a hidden skill so we are gucci
            theSkill = SkillFactory.getSkill(GameConstants.getHiddenSkill(attack.skill));
            attackEffect = attack.getAttackEffect(player, theSkill);
            if (attackEffect == null) {
                player.getClient().announce(MaplePacketCreator.enableActions());
                return;
            }
            if (player.getMp() < attackEffect.getMpCon()) {
                AutobanFactory.MPCON.addPoint(player.getAutobanManager(), "Skill: " + attack.skill + "; Player MP: " + player.getMp() + "; MP Needed: " + attackEffect.getMpCon());
            }
            if (attack.skill != Cleric.HEAL) {
                if (player.isAlive()) {
                    if (// Poison Bomb
                    attack.skill == NightWalker.POISON_BOMB)
                        attackEffect.applyTo(player, new Point(attack.position.x, attack.position.y));
                    else if (// prevent BP refreshing
                    attack.skill != Aran.BODY_PRESSURE)
                        attackEffect.applyTo(player);
                } else {
                    player.getClient().announce(MaplePacketCreator.enableActions());
                }
            }
            int mobCount = attackEffect.getMobCount();
            if (attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Page.FINAL_ATTACK_BW || attack.skill == Page.FINAL_ATTACK_SWORD || attack.skill == Fighter.FINAL_ATTACK_SWORD || attack.skill == Fighter.FINAL_ATTACK_AXE || attack.skill == Spearman.FINAL_ATTACK_SPEAR || attack.skill == Spearman.FINAL_ATTACK_POLEARM || attack.skill == WindArcher.FINAL_ATTACK || attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Hunter.FINAL_ATTACK || attack.skill == Crossbowman.FINAL_ATTACK) {
                // :(
                mobCount = 15;
            }
            if (attack.skill == Aran.HIDDEN_FULL_DOUBLE || attack.skill == Aran.HIDDEN_FULL_TRIPLE || attack.skill == Aran.HIDDEN_OVER_DOUBLE || attack.skill == Aran.HIDDEN_OVER_TRIPLE) {
                mobCount = 12;
            }
            if (attack.numAttacked > mobCount) {
                AutobanFactory.MOB_COUNT.autoban(player, "Skill: " + attack.skill + "; Count: " + attack.numAttacked + " Max: " + attackEffect.getMobCount());
                return;
            }
        }
        if (!player.isAlive()) {
            return;
        }
        // WTF IS THIS F3,1
        /*if (attackCount != attack.numDamage && attack.skill != ChiefBandit.MESO_EXPLOSION && attack.skill != NightWalker.VAMPIRE && attack.skill != WindArcher.WIND_SHOT && attack.skill != Aran.COMBO_SMASH && attack.skill != Aran.COMBO_FENRIR && attack.skill != Aran.COMBO_TEMPEST && attack.skill != NightLord.NINJA_AMBUSH && attack.skill != Shadower.NINJA_AMBUSH) {
                return;
            }*/
        int totDamage = 0;
        final MapleMap map = player.getMap();
        if (attack.skill == ChiefBandit.MESO_EXPLOSION) {
            int delay = 0;
            for (Integer oned : attack.allDamage.keySet()) {
                MapleMapObject mapobject = map.getMapObject(oned.intValue());
                if (mapobject != null && mapobject.getType() == MapleMapObjectType.ITEM) {
                    final MapleMapItem mapitem = (MapleMapItem) mapobject;
                    if (mapitem.getMeso() == 0) {
                        // Maybe it is possible some how?
                        return;
                    }
                    synchronized (mapitem) {
                        if (mapitem.isPickedUp()) {
                            return;
                        }
                        TimerManager.getInstance().schedule(new Runnable() {

                            @Override
                            public void run() {
                                map.pickItemDrop(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 4, 0), mapitem);
                            }
                        }, delay);
                        delay += 100;
                    }
                } else if (mapobject != null && mapobject.getType() != MapleMapObjectType.MONSTER) {
                    return;
                }
            }
        }
        for (Integer oned : attack.allDamage.keySet()) {
            final MapleMonster monster = map.getMonsterByOid(oned.intValue());
            if (monster != null) {
                double distance = player.getPosition().distanceSq(monster.getPosition());
                double distanceToDetect = 200000.0;
                if (attack.ranged)
                    distanceToDetect += 400000;
                if (attack.magic)
                    distanceToDetect += 200000;
                if (player.getJob().isA(MapleJob.ARAN1))
                    // Arans have extra range over normal warriors.
                    distanceToDetect += 200000;
                if (attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.BODY_PRESSURE)
                    distanceToDetect += 40000;
                else if (attack.skill == Bishop.GENESIS || attack.skill == ILArchMage.BLIZZARD || attack.skill == FPArchMage.METEOR_SHOWER)
                    distanceToDetect += 275000;
                else if (attack.skill == Hero.BRANDISH || attack.skill == DragonKnight.SPEAR_CRUSHER || attack.skill == DragonKnight.POLE_ARM_CRUSHER)
                    distanceToDetect += 40000;
                else if (attack.skill == DragonKnight.DRAGON_ROAR || attack.skill == SuperGM.SUPER_DRAGON_ROAR)
                    distanceToDetect += 250000;
                else if (attack.skill == Shadower.BOOMERANG_STEP)
                    distanceToDetect += 60000;
                if (distance > distanceToDetect) {
                    AutobanFactory.DISTANCE_HACK.alert(player, "Distance Sq to monster: " + distance + " SID: " + attack.skill + " MID: " + monster.getId());
                }
                int totDamageToOneMonster = 0;
                List<Integer> onedList = attack.allDamage.get(oned);
                for (Integer eachd : onedList) {
                    if (eachd < 0)
                        eachd += Integer.MAX_VALUE;
                    totDamageToOneMonster += eachd;
                }
                totDamage += totDamageToOneMonster;
                player.checkMonsterAggro(monster);
                if (player.getBuffedValue(MapleBuffStat.PICKPOCKET) != null && (attack.skill == 0 || attack.skill == Rogue.DOUBLE_STAB || attack.skill == Bandit.SAVAGE_BLOW || attack.skill == ChiefBandit.ASSAULTER || attack.skill == ChiefBandit.BAND_OF_THIEVES || attack.skill == Shadower.ASSASSINATE || attack.skill == Shadower.TAUNT || attack.skill == Shadower.BOOMERANG_STEP)) {
                    Skill pickpocket = SkillFactory.getSkill(ChiefBandit.PICKPOCKET);
                    int picklv = (player.isGM()) ? pickpocket.getMaxLevel() : player.getSkillLevel(pickpocket);
                    if (picklv > 0) {
                        int delay = 0;
                        final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
                        for (Integer eachd : onedList) {
                            eachd += Integer.MAX_VALUE;
                            if (pickpocket.getEffect(picklv).makeChanceResult()) {
                                final Integer eachdf;
                                if (eachd < 0)
                                    eachdf = eachd + Integer.MAX_VALUE;
                                else
                                    eachdf = eachd;
                                TimerManager.getInstance().schedule(new Runnable() {

                                    @Override
                                    public void run() {
                                        player.getMap().spawnMesoDrop(Math.min((int) Math.max(((double) eachdf / (double) 20000) * (double) maxmeso, (double) 1), maxmeso), new Point((int) (monster.getPosition().getX() + Randomizer.nextInt(100) - 50), (int) (monster.getPosition().getY())), monster, player, true, (byte) 2);
                                    }
                                }, delay);
                                delay += 100;
                            }
                        }
                    }
                } else if (attack.skill == Marauder.ENERGY_DRAIN || attack.skill == ThunderBreaker.ENERGY_DRAIN || attack.skill == NightWalker.VAMPIRE || attack.skill == Assassin.DRAIN) {
                    player.addHP(Math.min(monster.getMaxHp(), Math.min((int) ((double) totDamage * (double) SkillFactory.getSkill(attack.skill).getEffect(player.getSkillLevel(SkillFactory.getSkill(attack.skill))).getX() / 100.0), player.getMaxHp() / 2)));
                } else if (attack.skill == Bandit.STEAL) {
                    Skill steal = SkillFactory.getSkill(Bandit.STEAL);
                    if (monster.getStolen().size() < 1) {
                        // One steal per mob <3
                        if (steal.getEffect(player.getSkillLevel(steal)).makeChanceResult()) {
                            MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance();
                            List<Integer> dropPool = mi.retrieveDropPool(monster.getId());
                            if (!dropPool.isEmpty()) {
                                Integer rndPool = (int) Math.floor(Math.random() * dropPool.get(dropPool.size() - 1));
                                int i = 0;
                                while (rndPool >= dropPool.get(i)) i++;
                                List<MonsterDropEntry> toSteal = new ArrayList<>();
                                toSteal.add(mi.retrieveDrop(monster.getId()).get(i));
                                player.getMap().dropItemsFromMonster(toSteal, player, monster);
                                monster.addStolen(toSteal.get(0).itemId);
                            }
                        }
                    }
                } else if (attack.skill == FPArchMage.FIRE_DEMON) {
                    monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, SkillFactory.getSkill(FPArchMage.FIRE_DEMON).getEffect(player.getSkillLevel(SkillFactory.getSkill(FPArchMage.FIRE_DEMON))).getDuration() * 1000);
                } else if (attack.skill == ILArchMage.ICE_DEMON) {
                    monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, SkillFactory.getSkill(ILArchMage.ICE_DEMON).getEffect(player.getSkillLevel(SkillFactory.getSkill(ILArchMage.ICE_DEMON))).getDuration() * 1000);
                } else if (attack.skill == Outlaw.HOMING_BEACON || attack.skill == Corsair.BULLSEYE) {
                    player.setMarkedMonster(monster.getObjectId());
                    player.announce(MaplePacketCreator.giveBuff(1, attack.skill, Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, monster.getObjectId()))));
                }
                if (job == 2111 || job == 2112) {
                    if (player.getBuffedValue(MapleBuffStat.WK_CHARGE) != null) {
                        Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE);
                        if (totDamageToOneMonster > 0) {
                            MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false);
                            monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000);
                        }
                    }
                }
                if (player.getBuffedValue(MapleBuffStat.HAMSTRING) != null) {
                    Skill hamstring = SkillFactory.getSkill(Bowmaster.HAMSTRING);
                    if (hamstring.getEffect(player.getSkillLevel(hamstring)).makeChanceResult()) {
                        MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, hamstring.getEffect(player.getSkillLevel(hamstring)).getX()), hamstring, null, false);
                        monster.applyStatus(player, monsterStatusEffect, false, hamstring.getEffect(player.getSkillLevel(hamstring)).getY() * 1000);
                    }
                }
                if (player.getBuffedValue(MapleBuffStat.SLOW) != null) {
                    Skill slow = SkillFactory.getSkill(Evan.SLOW);
                    if (slow.getEffect(player.getSkillLevel(slow)).makeChanceResult()) {
                        MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, slow.getEffect(player.getSkillLevel(slow)).getX()), slow, null, false);
                        monster.applyStatus(player, monsterStatusEffect, false, slow.getEffect(player.getSkillLevel(slow)).getY() * 60 * 1000);
                    }
                }
                if (player.getBuffedValue(MapleBuffStat.BLIND) != null) {
                    Skill blind = SkillFactory.getSkill(Marksman.BLIND);
                    if (blind.getEffect(player.getSkillLevel(blind)).makeChanceResult()) {
                        MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.ACC, blind.getEffect(player.getSkillLevel(blind)).getX()), blind, null, false);
                        monster.applyStatus(player, monsterStatusEffect, false, blind.getEffect(player.getSkillLevel(blind)).getY() * 1000);
                    }
                }
                if (job == 121 || job == 122) {
                    for (int charge = 1211005; charge < 1211007; charge++) {
                        Skill chargeSkill = SkillFactory.getSkill(charge);
                        if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
                            if (totDamageToOneMonster > 0) {
                                if (charge == WhiteKnight.BW_ICE_CHARGE || charge == WhiteKnight.SWORD_ICE_CHARGE) {
                                    monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
                                    break;
                                }
                                if (charge == WhiteKnight.BW_FIRE_CHARGE || charge == WhiteKnight.SWORD_FIRE_CHARGE) {
                                    monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
                                    break;
                                }
                            }
                        }
                    }
                    if (job == 122) {
                        for (int charge = 1221003; charge < 1221004; charge++) {
                            Skill chargeSkill = SkillFactory.getSkill(charge);
                            if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
                                if (totDamageToOneMonster > 0) {
                                    monster.setTempEffectiveness(Element.HOLY, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
                                    break;
                                }
                            }
                        }
                    }
                } else if (player.getBuffedValue(MapleBuffStat.COMBO_DRAIN) != null) {
                    Skill skill;
                    if (player.getBuffedValue(MapleBuffStat.COMBO_DRAIN) != null) {
                        skill = SkillFactory.getSkill(21100005);
                        player.setHp(player.getHp() + ((totDamage * skill.getEffect(player.getSkillLevel(skill)).getX()) / 100), true);
                        player.updateSingleStat(MapleStat.HP, player.getHp());
                    }
                } else if (job == 412 || job == 422 || job == 1411) {
                    Skill type = SkillFactory.getSkill(player.getJob().getId() == 412 ? 4120005 : (player.getJob().getId() == 1411 ? 14110004 : 4220005));
                    if (player.getSkillLevel(type) > 0) {
                        MapleStatEffect venomEffect = type.getEffect(player.getSkillLevel(type));
                        for (int i = 0; i < attackCount; i++) {
                            if (venomEffect.makeChanceResult()) {
                                if (monster.getVenomMulti() < 3) {
                                    monster.setVenomMulti((monster.getVenomMulti() + 1));
                                    MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false);
                                    monster.applyStatus(player, monsterStatusEffect, false, venomEffect.getDuration(), true);
                                }
                            }
                        }
                    }
                } else if (job == 521 || job == 522) {
                    // from what I can gather this is how it should work
                    if (!monster.isBoss()) {
                        Skill type = SkillFactory.getSkill(Outlaw.FLAME_THROWER);
                        if (player.getSkillLevel(type) > 0) {
                            MapleStatEffect DoT = type.getEffect(player.getSkillLevel(type));
                            MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false);
                            monster.applyStatus(player, monsterStatusEffect, true, DoT.getDuration(), false);
                        }
                    }
                } else if (job >= 311 && job <= 322) {
                    if (!monster.isBoss()) {
                        Skill mortalBlow;
                        if (job == 311 || job == 312) {
                            mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW);
                        } else {
                            mortalBlow = SkillFactory.getSkill(Sniper.MORTAL_BLOW);
                        }
                        if (player.getSkillLevel(mortalBlow) > 0) {
                            MapleStatEffect mortal = mortalBlow.getEffect(player.getSkillLevel(mortalBlow));
                            if (monster.getHp() <= (monster.getStats().getHp() * mortal.getX()) / 100) {
                                if (Randomizer.rand(1, 100) <= mortal.getY()) {
                                    monster.getMap().killMonster(monster, player, true);
                                }
                            }
                        }
                    }
                }
                if (attack.skill != 0) {
                    if (attackEffect.getFixDamage() != -1) {
                        if (totDamageToOneMonster != attackEffect.getFixDamage() && totDamageToOneMonster != 0) {
                            AutobanFactory.FIX_DAMAGE.autoban(player, String.valueOf(totDamageToOneMonster) + " damage");
                        }
                        if (ServerConstants.USE_ULTRA_THREE_SNAILS) {
                            AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
                            int shellId;
                            switch(totDamageToOneMonster) {
                                case 10:
                                    shellId = 4000019;
                                    break;
                                case 25:
                                    shellId = 4000000;
                                    break;
                                default:
                                    shellId = 4000016;
                            }
                            if (api.haveItem(shellId, 1)) {
                                api.gainItem(shellId, (short) -1, false);
                                totDamageToOneMonster *= player.getLevel();
                            } else {
                                player.dropMessage(5, "You ran out of shells to activate the hidden power of Three Snails.");
                            }
                        }
                    }
                }
                if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.getMonsterStati().size() > 0) {
                    if (attackEffect.makeChanceResult()) {
                        monster.applyStatus(player, new MonsterStatusEffect(attackEffect.getMonsterStati(), theSkill, null, false), attackEffect.isPoison(), attackEffect.getDuration());
                    }
                }
                if (attack.isHH && !monster.isBoss()) {
                    map.damageMonster(player, monster, monster.getHp() - 1);
                } else if (attack.isHH) {
                    int HHDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Paladin.HEAVENS_HAMMER).getEffect(player.getSkillLevel(SkillFactory.getSkill(Paladin.HEAVENS_HAMMER))).getDamage() / 100));
                    map.damageMonster(player, monster, (int) (Math.floor(Math.random() * (HHDmg / 5) + HHDmg * .8)));
                } else if (attack.isTempest && !monster.isBoss()) {
                    map.damageMonster(player, monster, monster.getHp());
                } else if (attack.isTempest) {
                    int TmpDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Aran.COMBO_TEMPEST).getEffect(player.getSkillLevel(SkillFactory.getSkill(Aran.COMBO_TEMPEST))).getDamage() / 100));
                    map.damageMonster(player, monster, (int) (Math.floor(Math.random() * (TmpDmg / 5) + TmpDmg * .8)));
                } else {
                    map.damageMonster(player, monster, totDamageToOneMonster);
                }
                if (monster.isBuffed(MonsterStatus.WEAPON_REFLECT)) {
                    for (int i = 0; i < monster.getSkills().size(); i++) {
                        if (monster.getSkills().get(i).left == 145) {
                            MobSkill toUse = MobSkillFactory.getMobSkill(monster.getSkills().get(i).left, monster.getSkills().get(i).right);
                            player.addHP(-toUse.getX());
                            map.broadcastMessage(player, MaplePacketCreator.damagePlayer(0, monster.getId(), player.getId(), toUse.getX(), 0, 0, false, 0, true, monster.getObjectId(), 0, 0), true);
                        }
                    }
                }
                if (monster.isBuffed(MonsterStatus.MAGIC_REFLECT)) {
                    for (int i = 0; i < monster.getSkills().size(); i++) {
                        if (monster.getSkills().get(i).left == 145) {
                            MobSkill toUse = MobSkillFactory.getMobSkill(monster.getSkills().get(i).left, monster.getSkills().get(i).right);
                            player.addMP(-toUse.getY());
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : MapleMonsterInformationProvider(server.life.MapleMonsterInformationProvider) MonsterStatusEffect(client.status.MonsterStatusEffect) ArrayList(java.util.ArrayList) MapleMapObject(server.maps.MapleMapObject) Point(java.awt.Point) AbstractPlayerInteraction(scripting.AbstractPlayerInteraction) Point(java.awt.Point) MapleMap(server.maps.MapleMap) Skill(client.Skill) MobSkill(server.life.MobSkill) MapleStatEffect(server.MapleStatEffect) MonsterDropEntry(server.life.MonsterDropEntry) MapleMapItem(server.maps.MapleMapItem) MobSkill(server.life.MobSkill) MapleMonster(server.life.MapleMonster) Pair(tools.Pair)

Aggregations

MapleStatEffect (server.MapleStatEffect)21 MapleCharacter (client.MapleCharacter)10 Point (java.awt.Point)10 Skill (client.Skill)9 ArrayList (java.util.ArrayList)6 MapleMonster (server.life.MapleMonster)6 MobSkill (server.life.MobSkill)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 Pair (tools.Pair)5 Item (client.inventory.Item)3 MonsterStatusEffect (client.status.MonsterStatusEffect)3 MapleMap (server.maps.MapleMap)3 MapleBuffStat (client.MapleBuffStat)2 MapleInventory (client.inventory.MapleInventory)2 MapleWeaponType (client.inventory.MapleWeaponType)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 SpawnPoint (server.life.SpawnPoint)2 MapleMapItem (server.maps.MapleMapItem)2 MapleMapObject (server.maps.MapleMapObject)2