Search in sources :

Example 1 with MonsterStatus

use of client.status.MonsterStatus in project HeavenMS by ronancpl.

the class MapleMonster method applyStatus.

public boolean applyStatus(MapleCharacter from, final MonsterStatusEffect status, boolean poison, long duration, boolean venom) {
    switch(getMonsterEffectiveness(status.getSkill().getElement())) {
        case IMMUNE:
        case STRONG:
        case NEUTRAL:
            return false;
        case NORMAL:
        case WEAK:
            break;
        default:
            {
                System.out.println("Unknown elemental effectiveness: " + getMonsterEffectiveness(status.getSkill().getElement()));
                return false;
            }
    }
    if (status.getSkill().getId() == FPMage.ELEMENT_COMPOSITION) {
        // fp compo
        ElementalEffectiveness effectiveness = getMonsterEffectiveness(Element.POISON);
        if (effectiveness == ElementalEffectiveness.IMMUNE || effectiveness == ElementalEffectiveness.STRONG) {
            return false;
        }
    } else if (status.getSkill().getId() == ILMage.ELEMENT_COMPOSITION) {
        // il compo
        ElementalEffectiveness effectiveness = getMonsterEffectiveness(Element.ICE);
        if (effectiveness == ElementalEffectiveness.IMMUNE || effectiveness == ElementalEffectiveness.STRONG) {
            return false;
        }
    } else if (status.getSkill().getId() == NightLord.VENOMOUS_STAR || status.getSkill().getId() == Shadower.VENOMOUS_STAB || status.getSkill().getId() == NightWalker.VENOM) {
        // venom
        if (getMonsterEffectiveness(Element.POISON) == ElementalEffectiveness.WEAK) {
            return false;
        }
    }
    if (poison && hp.get() <= 1) {
        return false;
    }
    final Map<MonsterStatus, Integer> statis = status.getStati();
    if (stats.isBoss()) {
        if (!(statis.containsKey(MonsterStatus.SPEED) && statis.containsKey(MonsterStatus.NINJA_AMBUSH) && statis.containsKey(MonsterStatus.WATK))) {
            return false;
        }
    }
    if (statis.size() > 0) {
        statiLock.lock();
        try {
            for (MonsterStatus stat : statis.keySet()) {
                final MonsterStatusEffect oldEffect = stati.get(stat);
                if (oldEffect != null) {
                    oldEffect.removeActiveStatus(stat);
                    if (oldEffect.getStati().isEmpty()) {
                        oldEffect.cancelTask();
                        oldEffect.cancelDamageSchedule();
                    }
                }
            }
        } finally {
            statiLock.unlock();
        }
    }
    TimerManager timerManager = TimerManager.getInstance();
    final Runnable cancelTask = new Runnable() {

        @Override
        public void run() {
            if (isAlive()) {
                byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), status.getStati());
                map.broadcastMessage(packet, getPosition());
                MapleCharacter controller = getController();
                if (controller != null && !controller.isMapObjectVisible(MapleMonster.this)) {
                    controller.getClient().announce(packet);
                }
            }
            statiLock.lock();
            try {
                for (MonsterStatus stat : status.getStati().keySet()) {
                    stati.remove(stat);
                }
            } finally {
                statiLock.unlock();
            }
            setVenomMulti(0);
            status.cancelDamageSchedule();
        }
    };
    int animationTime;
    if (poison) {
        int poisonLevel = from.getSkillLevel(status.getSkill());
        int poisonDamage = Math.min(Short.MAX_VALUE, (int) (getMaxHp() / (70.0 - poisonLevel) + 0.999));
        status.setValue(MonsterStatus.POISON, Integer.valueOf(poisonDamage));
        animationTime = broadcastStatusEffect(status);
        status.setDamageSchedule(timerManager.register(new DamageTask(poisonDamage, from, status, cancelTask, 0), 1000, 1000));
    } else if (venom) {
        if (from.getJob() == MapleJob.NIGHTLORD || from.getJob() == MapleJob.SHADOWER || from.getJob().isA(MapleJob.NIGHTWALKER3)) {
            int poisonLevel, matk, jobid = from.getJob().getId();
            int skillid = (jobid == 412 ? NightLord.VENOMOUS_STAR : (jobid == 422 ? Shadower.VENOMOUS_STAB : NightWalker.VENOM));
            poisonLevel = from.getSkillLevel(SkillFactory.getSkill(skillid));
            if (poisonLevel <= 0) {
                return false;
            }
            matk = SkillFactory.getSkill(skillid).getEffect(poisonLevel).getMatk();
            int luk = from.getLuk();
            int maxDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.2 * luk * matk));
            int minDmg = (int) Math.ceil(Math.min(Short.MAX_VALUE, 0.1 * luk * matk));
            int gap = maxDmg - minDmg;
            if (gap == 0) {
                gap = 1;
            }
            int poisonDamage = 0;
            for (int i = 0; i < getVenomMulti(); i++) {
                poisonDamage += (Randomizer.nextInt(gap) + minDmg);
            }
            poisonDamage = Math.min(Short.MAX_VALUE, poisonDamage);
            status.setValue(MonsterStatus.VENOMOUS_WEAPON, Integer.valueOf(poisonDamage));
            status.setValue(MonsterStatus.POISON, Integer.valueOf(poisonDamage));
            animationTime = broadcastStatusEffect(status);
            status.setDamageSchedule(timerManager.register(new DamageTask(poisonDamage, from, status, cancelTask, 0), 1000, 1000));
        } else {
            return false;
        }
    /*
        } else if (status.getSkill().getId() == Hermit.SHADOW_WEB || status.getSkill().getId() == NightWalker.SHADOW_WEB) { //Shadow Web
            int webDamage = (int) (getMaxHp() / 50.0 + 0.999);
            status.setValue(MonsterStatus.SHADOW_WEB, Integer.valueOf(webDamage));
            animationTime = broadcastStatusEffect(status);
            status.setDamageSchedule(timerManager.schedule(new DamageTask(webDamage, from, status, cancelTask, 1), 3500));
            */
    } else if (status.getSkill().getId() == 4121004 || status.getSkill().getId() == 4221004) {
        // Ninja Ambush
        final Skill skill = SkillFactory.getSkill(status.getSkill().getId());
        final byte level = from.getSkillLevel(skill);
        final int damage = (int) ((from.getStr() + from.getLuk()) * (1.5 + (level * 0.05)) * skill.getEffect(level).getDamage());
        status.setValue(MonsterStatus.NINJA_AMBUSH, Integer.valueOf(damage));
        animationTime = broadcastStatusEffect(status);
        status.setDamageSchedule(timerManager.register(new DamageTask(damage, from, status, cancelTask, 2), 1000, 1000));
    } else {
        animationTime = broadcastStatusEffect(status);
    }
    statiLock.lock();
    try {
        for (MonsterStatus stat : status.getStati().keySet()) {
            stati.put(stat, status);
            alreadyBuffed.add(stat);
        }
    } finally {
        statiLock.unlock();
    }
    status.setCancelTask(timerManager.schedule(cancelTask, duration + animationTime - 100));
    return true;
}
Also used : MapleCharacter(client.MapleCharacter) MonsterStatusEffect(client.status.MonsterStatusEffect) MonsterStatus(client.status.MonsterStatus) TimerManager(server.TimerManager) Point(java.awt.Point) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Skill(client.Skill)

Example 2 with MonsterStatus

use of client.status.MonsterStatus in project HeavenMS by ronancpl.

the class MobSkill method applyEffect.

public void applyEffect(MapleCharacter player, MapleMonster monster, boolean skill, List<MapleCharacter> banishPlayers) {
    MapleDisease disease = null;
    Map<MonsterStatus, Integer> stats = new ArrayMap<MonsterStatus, Integer>();
    List<Integer> reflection = new LinkedList<Integer>();
    switch(skillId) {
        case 100:
        case 110:
        case 150:
            stats.put(MonsterStatus.WEAPON_ATTACK_UP, Integer.valueOf(x));
            break;
        case 101:
        case 111:
        case 151:
            stats.put(MonsterStatus.MAGIC_ATTACK_UP, Integer.valueOf(x));
            break;
        case 102:
        case 112:
        case 152:
            stats.put(MonsterStatus.WEAPON_DEFENSE_UP, Integer.valueOf(x));
            break;
        case 103:
        case 113:
        case 153:
            stats.put(MonsterStatus.MAGIC_DEFENSE_UP, Integer.valueOf(x));
            break;
        case 114:
            if (lt != null && rb != null && skill) {
                List<MapleMapObject> objects = getObjectsInRange(monster, MapleMapObjectType.MONSTER);
                final int hps = (getX() / 1000) * (int) (950 + 1050 * Math.random());
                for (MapleMapObject mons : objects) {
                    ((MapleMonster) mons).heal(hps, getY());
                }
            } else {
                monster.heal(getX(), getY());
            }
            break;
        case 120:
            disease = MapleDisease.SEAL;
            break;
        case 121:
            disease = MapleDisease.DARKNESS;
            break;
        case 122:
            disease = MapleDisease.WEAKEN;
            break;
        case 123:
            disease = MapleDisease.STUN;
            break;
        case 124:
            disease = MapleDisease.CURSE;
            break;
        case 125:
            disease = MapleDisease.POISON;
            break;
        case // Slow
        126:
            disease = MapleDisease.SLOW;
            break;
        case 127:
            if (lt != null && rb != null && skill) {
                for (MapleCharacter character : getPlayersInRange(monster, player)) {
                    character.dispel();
                }
            } else {
                player.dispel();
            }
            break;
        case // Seduce
        128:
            disease = MapleDisease.SEDUCE;
            break;
        case // Banish
        129:
            if (lt != null && rb != null && skill) {
                for (MapleCharacter chr : getPlayersInRange(monster, player)) {
                    banishPlayers.add(chr);
                }
            } else {
                banishPlayers.add(player);
            }
            break;
        case // Mist
        131:
            monster.getMap().spawnMist(new MapleMist(calculateBoundingBox(monster.getPosition(), true), monster, this), x * 10, false, false, false);
            break;
        case 132:
            disease = MapleDisease.CONFUSE;
            break;
        case // zombify
        133:
            disease = MapleDisease.ZOMBIFY;
            break;
        case 140:
            if (makeChanceResult() && !monster.isBuffed(MonsterStatus.MAGIC_IMMUNITY)) {
                stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
            }
            break;
        case 141:
            if (makeChanceResult() && !monster.isBuffed(MonsterStatus.WEAPON_IMMUNITY)) {
                stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
            }
            break;
        case // Weapon Reflect
        143:
            stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
            stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
            reflection.add(x);
            break;
        case // Magic Reflect
        144:
            stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
            stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
            reflection.add(x);
            break;
        case // Weapon / Magic reflect
        145:
            stats.put(MonsterStatus.WEAPON_REFLECT, Integer.valueOf(x));
            stats.put(MonsterStatus.WEAPON_IMMUNITY, Integer.valueOf(x));
            stats.put(MonsterStatus.MAGIC_REFLECT, Integer.valueOf(x));
            stats.put(MonsterStatus.MAGIC_IMMUNITY, Integer.valueOf(x));
            reflection.add(x);
            break;
        // accuracy up
        case 154:
        // avoid up
        case 155:
        case // speed up
        156:
            break;
        case // summon
        200:
            if (monster.getMap().getSpawnedMonstersOnMap() < 80) {
                for (Integer mobId : getSummons()) {
                    MapleMonster toSpawn = MapleLifeFactory.getMonster(mobId);
                    if (toSpawn != null) {
                        // no littering on BRPQ pls
                        if (GameConstants.isBossRush(monster.getMap().getId()))
                            toSpawn.disableDrops();
                        toSpawn.setPosition(monster.getPosition());
                        int ypos, xpos;
                        xpos = (int) monster.getPosition().getX();
                        ypos = (int) monster.getPosition().getY();
                        switch(mobId) {
                            case // Pap bomb high
                            8500003:
                                toSpawn.setFh((int) Math.ceil(Math.random() * 19.0));
                                ypos = -590;
                                break;
                            case // Pap bomb
                            8500004:
                                xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
                                if (ypos != -590) {
                                    ypos = (int) monster.getPosition().getY();
                                }
                                break;
                            case // Pianus bomb
                            8510100:
                                if (Math.ceil(Math.random() * 5) == 1) {
                                    ypos = 78;
                                    xpos = (int) Randomizer.nextInt(5) + (Randomizer.nextInt(2) == 1 ? 180 : 0);
                                } else {
                                    xpos = (int) (monster.getPosition().getX() + Randomizer.nextInt(1000) - 500);
                                }
                                break;
                        }
                        switch(monster.getMap().getId()) {
                            case // Pap map
                            220080001:
                                if (xpos < -890) {
                                    xpos = (int) (Math.ceil(Math.random() * 150) - 890);
                                } else if (xpos > 230) {
                                    xpos = (int) (230 - Math.ceil(Math.random() * 150));
                                }
                                break;
                            case // Pianus map
                            230040420:
                                if (xpos < -239) {
                                    xpos = (int) (Math.ceil(Math.random() * 150) - 239);
                                } else if (xpos > 371) {
                                    xpos = (int) (371 - Math.ceil(Math.random() * 150));
                                }
                                break;
                        }
                        toSpawn.setPosition(new Point(xpos, ypos));
                        if (toSpawn.getId() == 8500004) {
                            monster.getMap().spawnFakeMonster(toSpawn);
                        } else {
                            monster.getMap().spawnMonsterWithEffect(toSpawn, getSpawnEffect(), toSpawn.getPosition());
                        }
                    }
                }
            }
            break;
        default:
            System.out.println("Unhandled Mob skill: " + skillId);
            break;
    }
    if (stats.size() > 0) {
        if (lt != null && rb != null && skill) {
            for (MapleMapObject mons : getObjectsInRange(monster, MapleMapObjectType.MONSTER)) {
                ((MapleMonster) mons).applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
            }
        } else {
            monster.applyMonsterBuff(stats, getX(), getSkillId(), getDuration(), this, reflection);
        }
    }
    if (disease != null) {
        if (lt != null && rb != null && skill) {
            int i = 0;
            for (MapleCharacter character : getPlayersInRange(monster, player)) {
                if (!character.isActiveBuffedValue(2321005)) {
                    if (disease.equals(MapleDisease.SEDUCE)) {
                        if (i < 10) {
                            character.giveDebuff(MapleDisease.SEDUCE, this);
                            i++;
                        }
                    } else {
                        character.giveDebuff(disease, this);
                    }
                }
            }
        } else {
            player.giveDebuff(disease, this);
        }
    }
    monster.usedSkill(skillId, skillLevel, cooltime);
    monster.setMp(monster.getMp() - getMpCon());
}
Also used : MapleDisease(client.MapleDisease) MapleCharacter(client.MapleCharacter) MonsterStatus(client.status.MonsterStatus) ArrayMap(tools.ArrayMap) MapleMapObject(server.maps.MapleMapObject) Point(java.awt.Point) LinkedList(java.util.LinkedList) Point(java.awt.Point) MapleMist(server.maps.MapleMist)

Example 3 with MonsterStatus

use of client.status.MonsterStatus in project HeavenMS by ronancpl.

the class MapleMonster method debuffMob.

public void debuffMob(int skillid) {
    // skillid is not going to be used for now until I get warrior debuff working
    MonsterStatus[] stats = { MonsterStatus.WEAPON_ATTACK_UP, MonsterStatus.WEAPON_DEFENSE_UP, MonsterStatus.MAGIC_ATTACK_UP, MonsterStatus.MAGIC_DEFENSE_UP };
    statiLock.lock();
    try {
        for (int i = 0; i < stats.length; i++) {
            if (isBuffed(stats[i])) {
                final MonsterStatusEffect oldEffect = stati.get(stats[i]);
                byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), oldEffect.getStati());
                map.broadcastMessage(packet, getPosition());
                MapleCharacter controller = getController();
                if (controller != null && !controller.isMapObjectVisible(MapleMonster.this)) {
                    controller.getClient().announce(packet);
                }
                stati.remove(stats[i]);
            }
        }
    } finally {
        statiLock.unlock();
    }
}
Also used : MapleCharacter(client.MapleCharacter) MonsterStatusEffect(client.status.MonsterStatusEffect) MonsterStatus(client.status.MonsterStatus) Point(java.awt.Point)

Example 4 with MonsterStatus

use of client.status.MonsterStatus in project HeavenMS by ronancpl.

the class MapleMonster method applyMonsterBuff.

public void applyMonsterBuff(final Map<MonsterStatus, Integer> stats, final int x, int skillId, long duration, MobSkill skill, final List<Integer> reflection) {
    TimerManager timerManager = TimerManager.getInstance();
    final Runnable cancelTask = new Runnable() {

        @Override
        public void run() {
            if (isAlive()) {
                byte[] packet = MaplePacketCreator.cancelMonsterStatus(getObjectId(), stats);
                map.broadcastMessage(packet, getPosition());
                MapleCharacter controller = getController();
                if (controller != null && !controller.isMapObjectVisible(MapleMonster.this)) {
                    controller.getClient().announce(packet);
                }
                statiLock.lock();
                try {
                    for (final MonsterStatus stat : stats.keySet()) {
                        stati.remove(stat);
                    }
                } finally {
                    statiLock.unlock();
                }
            }
        }
    };
    final MonsterStatusEffect effect = new MonsterStatusEffect(stats, null, skill, true);
    byte[] packet = MaplePacketCreator.applyMonsterStatus(getObjectId(), effect, reflection);
    map.broadcastMessage(packet, getPosition());
    statiLock.lock();
    try {
        for (MonsterStatus stat : stats.keySet()) {
            stati.put(stat, effect);
            alreadyBuffed.add(stat);
        }
    } finally {
        statiLock.unlock();
    }
    MapleCharacter controller = getController();
    if (controller != null && !controller.isMapObjectVisible(this)) {
        controller.getClient().announce(packet);
    }
    effect.setCancelTask(timerManager.schedule(cancelTask, duration));
}
Also used : MapleCharacter(client.MapleCharacter) MonsterStatusEffect(client.status.MonsterStatusEffect) MonsterStatus(client.status.MonsterStatus) TimerManager(server.TimerManager)

Example 5 with MonsterStatus

use of client.status.MonsterStatus in project HeavenMS by ronancpl.

the class MaplePacketCreator method applyMonsterStatus.

public static byte[] applyMonsterStatus(final int oid, final MonsterStatusEffect mse, final List<Integer> reflection) {
    final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
    mplew.writeShort(SendOpcode.APPLY_MONSTER_STATUS.getValue());
    mplew.writeInt(oid);
    mplew.writeLong(0);
    writeIntMask(mplew, mse.getStati());
    for (Map.Entry<MonsterStatus, Integer> stat : mse.getStati().entrySet()) {
        mplew.writeShort(stat.getValue());
        if (mse.isMonsterSkill()) {
            mplew.writeShort(mse.getMobSkill().getSkillId());
            mplew.writeShort(mse.getMobSkill().getSkillLevel());
        } else {
            mplew.writeInt(mse.getSkill().getId());
        }
        // might actually be the buffTime but it's not displayed anywhere
        mplew.writeShort(-1);
    }
    // size
    int size = mse.getStati().size();
    if (reflection != null) {
        for (Integer ref : reflection) {
            mplew.writeInt(ref);
        }
        if (reflection.size() > 0) {
            // This gives 2 buffs per reflection but it's really one buff
            size /= 2;
        }
    }
    // size
    mplew.write(size);
    mplew.writeInt(0);
    return mplew.getPacket();
}
Also used : MaplePacketLittleEndianWriter(tools.data.output.MaplePacketLittleEndianWriter) MonsterStatus(client.status.MonsterStatus) MapleMap(server.maps.MapleMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) Point(java.awt.Point)

Aggregations

MonsterStatus (client.status.MonsterStatus)7 Point (java.awt.Point)6 MapleCharacter (client.MapleCharacter)4 MonsterStatusEffect (client.status.MonsterStatusEffect)3 TimerManager (server.TimerManager)2 ArrayMap (tools.ArrayMap)2 MapleDisease (client.MapleDisease)1 Skill (client.Skill)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 MapleData (provider.MapleData)1 MapleMap (server.maps.MapleMap)1 MapleMapObject (server.maps.MapleMapObject)1 MapleMist (server.maps.MapleMist)1 Pair (tools.Pair)1 MaplePacketLittleEndianWriter (tools.data.output.MaplePacketLittleEndianWriter)1