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);
}
}
}
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;
}
}
}
}
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();
}
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;
}
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();
}
}
Aggregations