package client; import client.MapleTrait.MapleTraitType; import client.inventory.Equip; import client.inventory.Item; import client.inventory.MapleInventoryType; import client.inventory.MapleWeaponType; import constants.EventConstants; import constants.GameConstants; import handling.world.World; import handling.world.guild.MapleGuild; import handling.world.guild.MapleGuildSkill; import java.io.Serializable; import java.util.ArrayList; import java.util.Calendar; import java.util.EnumMap; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import server.MapleInventoryManipulator; import server.MapleItemInformationProvider; import server.MapleStatEffect; import server.StructItemOption; import server.StructSetItem; import server.StructSetItem.SetItem; import server.life.Element; import tools.Pair; import tools.Triple; import tools.data.MaplePacketLittleEndianWriter; import tools.packet.CField.EffectPacket; import tools.packet.CWvsContext.InventoryPacket; import tools.packet.JobPacket; public class PlayerStats implements Serializable { private static final long serialVersionUID = -679541993413738569L; private List<Triple<Integer, String, Integer>> psdSkills = new ArrayList<>(); private final Map<Integer, Integer> setHandling = new HashMap<>(), skillsIncrement = new HashMap<>(), damageIncrease = new HashMap<>(); private final EnumMap<Element, Integer> elemBoosts = new EnumMap<>(Element.class); private final List<Equip> durabilityHandling = new ArrayList<>(), equipLevelHandling = new ArrayList<>(); private transient float shouldHealHP, shouldHealMP; private transient short passive_sharpeye_min_percent, passive_sharpeye_percent, crit_rate; private transient byte passive_mastery; public transient int localstr, localdex, localluk, localint_, localmaxhp, localmaxmp, magic, watk, hands, accuracy, targetPlus; private transient float localmaxbasedamage, localmaxbasepvpdamage, localmaxbasepvpdamageL; public transient boolean equippedWelcomeBackRing, hasClone, Berserk; public transient double expBuff, dropBuff, mesoBuff, cashBuff, mesoGuard, mesoGuardMeso, expMod, dropMod, pickupRange, dam_r, bossdam_r; public transient int recoverHP, recoverMP, mpconReduce, mpconPercent, incMesoProp, reduceCooltime, coolTimeR, suddenDeathR, expLossReduceR, DAMreflect, DAMreflect_rate, ignoreDAMr, ignoreDAMr_rate, ignoreDAM, ignoreDAM_rate, hpRecover, hpRecoverProp, hpRecoverPercent, mpRecover, mpRecoverProp, RecoveryUP, BuffUP, RecoveryUP_Skill, BuffUP_Skill, incAllskill, combatOrders, ignoreTargetDEF, defRange, BuffUP_Summon, dodgeChance, speed, jump, harvestingTool, equipmentBonusExp, cashMod, levelBonus, ASR, TER, pickRate, decreaseDebuff, equippedFairy, equippedSummon, pvpDamage, hpRecoverTime, mpRecoverTime, dot, dotTime, questBonus, pvpRank, pvpExp, wdef, mdef, trueMastery, damX; public transient int def, element_ice, element_fire, element_light, element_psn; public int hp, maxhp, mp, maxmp, str, dex, luk, int_; private transient int percent_hp, percent_mp, percent_str, percent_dex, percent_int, percent_luk, percent_acc, percent_atk, percent_matk, percent_wdef, percent_mdef, add_hp, add_mp, add_str, add_dex, add_int, add_luk, add_acc, add_atk, add_matk, add_wdef, add_mdef; public void recalcLocalStats(MapleCharacter chra) { recalcLocalStats(false, chra); } private void resetLocalStats(final int job) { accuracy = 0; wdef = 0; mdef = 0; damX = 0; localdex = getDex(); localint_ = getInt(); localstr = getStr(); localluk = getLuk(); speed = 100; jump = 100; pickupRange = 0.0; decreaseDebuff = 0; ASR = 0; TER = 0; dot = 0; questBonus = 1; dotTime = 0; trueMastery = 0; percent_wdef = 0; percent_mdef = 0; percent_hp = 0; percent_mp = 0; targetPlus = 0; percent_str = 0; percent_dex = 0; percent_int = 0; percent_luk = 0; percent_acc = 0; percent_atk = 0; percent_matk = 0; add_wdef = 0; add_mdef = 0; add_hp = 0; add_mp = 0; add_str = 0; add_dex = 0; add_int = 0; add_luk = 0; add_acc = 0; add_atk = 0; add_matk = 0; crit_rate = 5; passive_sharpeye_min_percent = 20; passive_sharpeye_percent = 50; magic = 0; watk = 0; dodgeChance = 0; pvpDamage = 0; mesoGuard = 50.0; mesoGuardMeso = 0.0; dam_r = 100.0; bossdam_r = 100.0; expBuff = 100.0; cashBuff = 100.0; dropBuff = 100.0; mesoBuff = 100.0; recoverHP = 0; recoverMP = 0; mpconReduce = 0; mpconPercent = 100; incMesoProp = 0; reduceCooltime = 0; coolTimeR = 0; suddenDeathR = 0; expLossReduceR = 0; DAMreflect = 0; DAMreflect_rate = 0; ignoreDAMr = 0; ignoreDAMr_rate = 0; ignoreDAM = 0; ignoreDAM_rate = 0; ignoreTargetDEF = 0; targetPlus = 0; hpRecover = 0; hpRecoverProp = 0; hpRecoverPercent = 0; mpRecover = 0; mpRecoverProp = 0; pickRate = 0; equippedWelcomeBackRing = false; equippedFairy = 0; equippedSummon = 0; hasClone = false; Berserk = false; equipmentBonusExp = 0; RecoveryUP = 0; BuffUP = 0; RecoveryUP_Skill = 0; BuffUP_Skill = 0; BuffUP_Summon = 0; dropMod = 1.0; expMod = 1.0; cashMod = 1; levelBonus = 0; incAllskill = 0; combatOrders = 0; defRange = isRangedJob(job) ? 200 : 0; durabilityHandling.clear(); equipLevelHandling.clear(); skillsIncrement.clear(); damageIncrease.clear(); setHandling.clear(); harvestingTool = 0; element_fire = 100; element_ice = 100; element_light = 100; element_psn = 100; def = 100; } public void recalcLocalStats(boolean first_login, MapleCharacter chra) { if (chra.isClone()) { return; //clones share PlayerStats objects and do not need to be recalculated } final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); int oldmaxhp = localmaxhp; int localmaxhp_ = getMaxHp(); int localmaxmp_ = getMaxMp(); resetLocalStats(chra.getJob()); for (MapleTraitType t : MapleTraitType.values()) { chra.getTrait(t).clearLocalExp(); } StructItemOption soc; final Map<Skill, SkillEntry> sData = new HashMap<>(); final Iterator<Item> itera = chra.getInventory(MapleInventoryType.EQUIPPED).newList().iterator(); while (itera.hasNext()) { final Equip equip = (Equip) itera.next(); if (equip.getPosition() == -11) { if (GameConstants.isMagicWeapon(equip.getItemId())) { final Map<String, Integer> eqstat = MapleItemInformationProvider.getInstance().getEquipStats(equip.getItemId()); if (eqstat != null) { //slow, poison, darkness, seal, freeze if (eqstat.containsKey("incRMAF")) { element_fire = eqstat.get("incRMAF"); } if (eqstat.containsKey("incRMAI")) { element_ice = eqstat.get("incRMAI"); } if (eqstat.containsKey("incRMAL")) { element_light = eqstat.get("incRMAL"); } if (eqstat.containsKey("incRMAS")) { element_psn = eqstat.get("incRMAS"); } if (eqstat.containsKey("elemDefault")) { def = eqstat.get("elemDefault"); } } } } if ((equip.getItemId() / 10000 == 166 && equip.getAndroid() != null || equip.getItemId() / 10000 == 167) && chra.getAndroid() == null) { final Equip android = (Equip) chra.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -27); final Equip heart = (Equip) chra.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -28); if (android != null && heart != null) { chra.setAndroid(equip.getAndroid()); } } //if (equip.getItemId() / 1000 == 1099) { // equippedForce += equip.getMp(); //} chra.getTrait(MapleTraitType.craft).addLocalExp(equip.getHands()); accuracy += equip.getAcc(); localmaxhp_ += equip.getHp(); localmaxmp_ += equip.getMp(); localdex += equip.getDex(); localint_ += equip.getInt(); localstr += equip.getStr(); localluk += equip.getLuk(); watk += equip.getWatk(); magic += equip.getMatk(); wdef += equip.getWdef(); mdef += equip.getMdef(); speed += equip.getSpeed(); jump += equip.getJump(); pvpDamage += equip.getPVPDamage(); bossdam_r += equip.getBossDamage(); ignoreTargetDEF += equip.getIgnorePDR(); dam_r *= (Double.valueOf(equip.getTotalDamage()) + 100.0) / 100.0; percent_str += equip.getAllStat(); percent_dex += equip.getAllStat(); percent_int += equip.getAllStat(); percent_luk += equip.getAllStat(); switch (equip.getItemId()) { case 1112127: equippedWelcomeBackRing = true; break; case 1122017: equippedFairy = 10; break; case 1122158: equippedFairy = 5; break; case 1112594: equippedSummon = 1085; break; case 1112585: equippedSummon = 1085; break; case 1112586: equippedSummon = 1087; break; case 1112663: equippedSummon = 1179; break; default: for (int eb_bonus : GameConstants.Equipments_Bonus) { if (equip.getItemId() == eb_bonus) { //equipmentBonusExp += GameConstants.Equipment_Bonus_EXP(eb_bonus); break; } } break; } final Integer set = ii.getSetItemID(equip.getItemId()); if (set != null && set > 0) { int value = 1; if (setHandling.containsKey(set)) { value += setHandling.get(set).intValue(); } setHandling.put(set, value); //id of Set, number of items to go with the set } if (equip.getIncSkill() > 0 && ii.getEquipSkills(equip.getItemId()) != null) { for (final int zzz : ii.getEquipSkills(equip.getItemId())) { final Skill skil = SkillFactory.getSkill(zzz); if (skil != null && skil.canBeLearnedBy(chra.getJob())) { //dont go over masterlevel :D int value = 1; if (skillsIncrement.get(skil.getId()) != null) { value += skillsIncrement.get(skil.getId()); } skillsIncrement.put(skil.getId(), value); } } } final Pair<Integer, Integer> ix = handleEquipAdditions(ii, chra, first_login, sData, equip.getItemId()); if (ix != null) { localmaxhp_ += ix.getLeft(); localmaxmp_ += ix.getRight(); } if (equip.getState() >= 17) { final int[] potentials = {equip.getPotential1(), equip.getPotential2(), equip.getPotential3(), equip.getBonusPotential1(), equip.getBonusPotential2()}; for (final int i : potentials) { if (i > 0) { soc = ii.getPotentialInfo(i).get(ii.getReqLevel(equip.getItemId()) / 10); if (soc != null) { localmaxhp_ += soc.get("incMHP"); localmaxmp_ += soc.get("incMMP"); handleItemOption(soc, chra, first_login, sData); } } } } if (equip.getSocketState() > 15) { final int[] sockets = {equip.getSocket1(), equip.getSocket2(), equip.getSocket3()}; for (final int i : sockets) { if (i > 0) { soc = ii.getSocketInfo(i); if (soc != null) { localmaxhp_ += soc.get("incMHP"); localmaxmp_ += soc.get("incMMP"); handleItemOption(soc, chra, first_login, sData); } } } } if (equip.getDurability() > 0) { durabilityHandling.add((Equip) equip); } if (GameConstants.getMaxLevel(equip.getItemId()) > 0 && (GameConstants.getStatFromWeapon(equip.getItemId()) == null ? (equip.getEquipLevel() <= GameConstants.getMaxLevel(equip.getItemId())) : (equip.getEquipLevel() < GameConstants.getMaxLevel(equip.getItemId())))) { equipLevelHandling.add((Equip) equip); } } final Iterator<Entry<Integer, Integer>> iter = setHandling.entrySet().iterator(); while (iter.hasNext()) { final Entry<Integer, Integer> entry = iter.next(); final StructSetItem set = ii.getSetItem(entry.getKey()); if (set != null) { final Map<Integer, SetItem> itemz = set.getItems(); for (Entry<Integer, SetItem> ent : itemz.entrySet()) { if (ent.getKey() <= entry.getValue()) { SetItem se = ent.getValue(); localstr += se.incSTR + se.incAllStat; localdex += se.incDEX + se.incAllStat; localint_ += se.incINT + se.incAllStat; localluk += se.incLUK + se.incAllStat; watk += se.incPAD; magic += se.incMAD; speed += se.incSpeed; accuracy += se.incACC; localmaxhp_ += se.incMHP; localmaxmp_ += se.incMMP; percent_hp += se.incMHPr; percent_mp += se.incMMPr; wdef += se.incPDD; mdef += se.incMDD; if (se.option1 > 0 && se.option1Level > 0) { soc = ii.getPotentialInfo(se.option1).get(se.option1Level); if (soc != null) { localmaxhp_ += soc.get("incMHP"); localmaxmp_ += soc.get("incMMP"); handleItemOption(soc, chra, first_login, sData); } } if (se.option2 > 0 && se.option2Level > 0) { soc = ii.getPotentialInfo(se.option2).get(se.option2Level); if (soc != null) { localmaxhp_ += soc.get("incMHP"); localmaxmp_ += soc.get("incMMP"); handleItemOption(soc, chra, first_login, sData); } } } } } } handleProfessionTool(chra); for (Item item : chra.getInventory(MapleInventoryType.CASH).newList()) { if (item.getItemId() / 100000 == 52) { if (expMod < 3 && (item.getItemId() == 5211060 || item.getItemId() == 5211050 || item.getItemId() == 5211051 || item.getItemId() == 5211052 || item.getItemId() == 5211053 || item.getItemId() == 5211054)) { expMod = 3.0; //overwrite } else if (expMod < 2 && (item.getItemId() == 5210000 || item.getItemId() == 5210001 || item.getItemId() == 5210002 || item.getItemId() == 5210003 || item.getItemId() == 5210004 || item.getItemId() == 5210005 || item.getItemId() == 5211061 || item.getItemId() == 5211000 || item.getItemId() == 5211001 || item.getItemId() == 5211002 || item.getItemId() == 5211003 || item.getItemId() == 5211046 || item.getItemId() == 5211047 || item.getItemId() == 5211048 || item.getItemId() == 5211049)) { expMod = 2.0; } else if (expMod < 1.5 && (item.getItemId() == 5211068)) { expMod = 1.5; } } else if (dropMod == 1.0 && item.getItemId() / 10000 == 536) { if (item.getItemId() >= 5360000 && item.getItemId() < 5360100) { dropMod = 2.0; } } else if (item.getItemId() == 5710000) { questBonus = 2; } else if (item.getItemId() == 5590000) { levelBonus += 5; } } if (dropMod > 0 && EventConstants.DoubleTime) { dropMod *= 2.0; } if (expMod > 0 && EventConstants.DoubleTime) { expMod *= 2.0; } for (Item item : chra.getInventory(MapleInventoryType.ETC).list()) { switch (item.getItemId()) { case 4030003: pickupRange = Double.POSITIVE_INFINITY; break; case 4030004: hasClone = true; break; case 4031864: cashMod = 2; break; } } if (first_login && chra.getLevel() >= 30) { if (chra.isGM()) { //!job lol for (int i = 0; i < allJobs.length; i++) { sData.put(SkillFactory.getSkill(1085 + allJobs[i]), new SkillEntry((byte) 1, (byte) 0, -1)); sData.put(SkillFactory.getSkill(1087 + allJobs[i]), new SkillEntry((byte) 1, (byte) 0, -1)); } } else { sData.put(SkillFactory.getSkill(getSkillByJob(1085, chra.getJob())), new SkillEntry((byte) 1, (byte) 0, -1)); sData.put(SkillFactory.getSkill(getSkillByJob(1087, chra.getJob())), new SkillEntry((byte) 1, (byte) 0, -1)); } } // add to localmaxhp_ if percentage plays a role in it, else add_hp handleBuffStats(chra); Integer buff = chra.getBuffedValue(MapleBuffStat.ENHANCED_MAXHP); if (buff != null) { localmaxhp_ += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ENHANCED_MAXMP); if (buff != null) { localmaxmp_ += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.HP_BOOST); if (buff != null) { localmaxhp_ += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.MP_BOOST); if (buff != null) { localmaxmp_ += buff.intValue(); } handlePassiveSkills(chra); handleHyperPassiveSkills(chra); if (chra.getGuildId() > 0) { final MapleGuild g = World.Guild.getGuild(chra.getGuildId()); if (g != null && g.getSkills().size() > 0) { final long now = System.currentTimeMillis(); for (MapleGuildSkill gs : g.getSkills()) { if (gs.timestamp > now && gs.activator.length() > 0) { final MapleStatEffect e = SkillFactory.getSkill(gs.skillID).getEffect(gs.level); crit_rate += e.getCr(); watk += e.getAttackX(); magic += e.getMagicX(); expBuff *= (e.getEXPRate() + 100.0) / 100.0; dodgeChance += e.getER(); percent_wdef += e.getWDEFRate(); percent_mdef += e.getMDEFRate(); } } } } for (Pair<Integer, Integer> ix : chra.getCharacterCard().getCardEffects()) { final MapleStatEffect e = SkillFactory.getSkill(ix.getLeft()).getEffect(ix.getRight()); percent_wdef += e.getWDEFRate(); watk += (e.getLevelToWatk() * chra.getLevel()); percent_hp += e.getPercentHP(); percent_mp += e.getPercentMP(); magic += (e.getLevelToMatk() * chra.getLevel()); RecoveryUP += e.getMPConsumeEff(); percent_acc += e.getPercentAcc(); crit_rate += e.getCr(); jump += e.getPassiveJump(); speed += e.getPassiveSpeed(); dodgeChance += e.getPercentAvoid(); damX += (e.getLevelToDamage() * chra.getLevel()); BuffUP_Summon += e.getSummonTimeInc(); expLossReduceR += e.getEXPLossRate(); ASR += e.getASRRate(); //ignoreMobDamR suddenDeathR += e.getSuddenDeathR(); BuffUP_Skill += e.getBuffTimeRate(); //onHitHpRecoveryR //onHitMpRecoveryR coolTimeR += e.getCooltimeReduceR(); incMesoProp += e.getMesoAcquisition(); damX += Math.floor((e.getHpToDamage() * oldmaxhp) / 100.0f); damX += Math.floor((e.getMpToDamage() * oldmaxhp) / 100.0f); //finalAttackDamR passive_sharpeye_percent += e.getCriticalMax(); ignoreTargetDEF += e.getIgnoreMob(); localstr += e.getStrX(); localdex += e.getDexX(); localint_ += e.getIntX(); localluk += e.getLukX(); localmaxhp_ += e.getMaxHpX(); localmaxmp_ += e.getMaxMpX(); watk += e.getAttackX(); magic += e.getMagicX(); bossdam_r += e.getBossDamage(); } localstr += Math.floor((localstr * percent_str) / 100.0f); localdex += Math.floor((localdex * percent_dex) / 100.0f); localint_ += Math.floor((localint_ * percent_int) / 100.0f); localluk += Math.floor((localluk * percent_luk) / 100.0f); if (localint_ > localdex) { accuracy += localint_ + Math.floor(localluk * 1.2); } else { accuracy += localluk + Math.floor(localdex * 1.2); } watk += Math.floor((watk * percent_atk) / 100.0f); magic += Math.floor((magic * percent_matk) / 100.0f); localint_ += Math.floor((localint_ * percent_matk) / 100.0f); wdef += Math.floor((localstr * 1.2) + ((localdex + localluk) * 0.5) + (localint_ * 0.4)); mdef += Math.floor((localstr * 0.4) + ((localdex + localluk) * 0.5) + (localint_ * 1.2)); wdef += Math.min(30000, Math.floor((wdef * percent_wdef) / 100.0f)); mdef += Math.min(30000, Math.floor((wdef * percent_mdef) / 100.0f)); hands = localdex + localint_ + localluk; calculateFame(chra); ignoreTargetDEF += chra.getTrait(MapleTraitType.charisma).getLevel() / 10; pvpDamage += chra.getTrait(MapleTraitType.charisma).getLevel() / 10; ASR += chra.getTrait(MapleTraitType.will).getLevel() / 5; accuracy += Math.floor((accuracy * percent_acc) / 100.0f); accuracy += chra.getTrait(MapleTraitType.insight).getLevel() * 15 / 10; localmaxhp_ += Math.floor((percent_hp * localmaxhp_) / 100.0f); localmaxhp_ += chra.getTrait(MapleTraitType.will).getLevel() * 20; localmaxhp = Math.min(500000, Math.abs(Math.max(-500000, localmaxhp_))); localmaxmp_ += Math.floor((percent_mp * localmaxmp_) / 100.0f); localmaxmp_ += chra.getTrait(MapleTraitType.sense).getLevel() * 20; localmaxmp = Math.min(500000, Math.abs(Math.max(-500000, localmaxmp_))); if (chra.getEventInstance() != null && chra.getEventInstance().getName().startsWith("PVP")) { //hack MapleStatEffect eff; localmaxhp = Math.min(40000, localmaxhp * 3); //approximate. localmaxmp = Math.min(20000, localmaxmp * 2); //not sure on 20000 cap for (int i : pvpSkills) { Skill skil = SkillFactory.getSkill(i); if (skil != null && skil.canBeLearnedBy(chra.getJob())) { sData.put(skil, new SkillEntry((byte) 1, (byte) 0, -1)); eff = skil.getEffect(1); switch ((i / 1000000) % 10) { case 1: if (eff.getX() > 0) { pvpDamage += (wdef / eff.getX()); } break; case 3: hpRecoverProp += eff.getProb(); hpRecover += eff.getX(); mpRecoverProp += eff.getProb(); mpRecover += eff.getX(); break; case 5: crit_rate += eff.getProb(); passive_sharpeye_percent = 100; break; } break; } } eff = chra.getStatForBuff(MapleBuffStat.MORPH); if (eff != null && eff.getSourceId() % 10000 == 1105) { //ice knight localmaxhp = 500000; localmaxmp = 500000; } } chra.changeSkillLevel_Skip(sData, false); if (GameConstants.isDemonSlayer(chra.getJob())) { localmaxmp = GameConstants.getMPByJob(chra.getJob()); } else if (GameConstants.isZero(chra.getJob())) { localmaxmp = 100; } if (GameConstants.isDemonAvenger(chra.getJob())) { chra.getClient().getSession().write(JobPacket.AvengerPacket.giveAvengerHpBuff(hp)); } CalcPassive_SharpEye(chra); CalcPassive_Mastery(chra); recalcPVPRank(chra); if (first_login) { chra.silentEnforceMaxHpMp(); relocHeal(chra); } else { chra.enforceMaxHpMp(); } calculateMaxBaseDamage(Math.max(magic, watk), pvpDamage, chra); trueMastery = Math.min(100, trueMastery); passive_sharpeye_min_percent = (short) Math.min(passive_sharpeye_min_percent, passive_sharpeye_percent); if (oldmaxhp != 0 && oldmaxhp != localmaxhp) { chra.updatePartyMemberHP(); } } public List<Triple<Integer, String, Integer>> getPsdSkills(){ return psdSkills; } private void handlePassiveSkills(MapleCharacter chra) { Skill bx; int bof; MapleStatEffect eff; if (GameConstants.isKOC(chra.getJob())) { bx = SkillFactory.getSkill(2000006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getX(); percent_mp += eff.getX(); } } psdSkills.clear(); for(Skill sk : chra.getSkills().keySet()){ if(sk.getPsd() == 1){ Triple<Integer, String, Integer> psdSkill = new Triple<>(0, "", 0); psdSkill.left = sk.getPsdSkill(); psdSkill.mid = sk.getPsdDamR(); //This only handles damage increases; some skills have effects other than that, so TODO psdSkill.mid = sk.getPsdtarget(); psdSkill.right = sk.getId(); psdSkills.add(psdSkill); } } switch (chra.getJob()) { case 200: case 210: case 211: case 212: case 220: case 221: case 222: case 230: case 231: case 232: { bx = SkillFactory.getSkill(2000006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_mp += bx.getEffect(bof).getPercentMP(); } break; } case 1200: case 1210: case 1211: case 1212: { bx = SkillFactory.getSkill(12000005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_mp += bx.getEffect(bof).getPercentMP(); } bx = SkillFactory.getSkill(12110000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { TER += bx.getEffect(bof).getX(); } break; } case 1100: case 1110: case 1111: case 1112: { bx = SkillFactory.getSkill(11000005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } break; } case 2003: // Phantom noob // Phantom Instinct - 20030204 // Dexterous Training - 20030206 bx = SkillFactory.getSkill(20030204); // +10% crit rate bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(20030206); // +40 DEX, Base Avoidability: +20% bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localdex += eff.getDexX(); dodgeChance += eff.getER(); } break; case 2400: case 2410: case 2411: case 2412: { // Phantom // Blanc Carte - 24100003 // Cane Mastery - 24100004 // Luck of Phantom Thief - 24111002 // 24111003- uses monlight effect, but is Misfortune Protection // 24110004 - Flash and Flee -> active // 24111005 - Moonlight // 24111006 - Phantom Charge // 24111008- Breeze Carte, (hidden), linked to phantom charge // 24121000 - Ultimate Drive // 24120002 - Noir Carte // 24121003 - Twilight // 24121004 - Pray of Aria // 24121005 - Tempest of Card // 24120006 - Cane Expert // 24121007 - Soul Steal // 24121008 - Maple Warrior // 24121009 - Hero's will // 24121010 - Some linked skill (Twilight) bx = SkillFactory.getSkill(24001002); // Swift Phantom bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); speed += eff.getPassiveSpeed(); jump += eff.getPassiveJump(); } bx = SkillFactory.getSkill(24000003); // Quick Evasion bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dodgeChance += eff.getX(); } bx = SkillFactory.getSkill(24100006); //Luck Monopoly bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localluk += eff.getLukX(); } bx = SkillFactory.getSkill(24110007); // Acute Sense bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(24111002); //Luck of Phantom Thief bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localluk += eff.getLukX(); } break; } case 501: case 530: case 531: case 532: bx = SkillFactory.getSkill(5010003); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getAttackX(); } bx = SkillFactory.getSkill(5300008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(5311001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(5301001, (int) bx.getEffect(bof).getDAMRate()); } bx = SkillFactory.getSkill(5310007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getHpR(); ASR += eff.getASRRate(); percent_wdef += eff.getWDEFRate(); } bx = SkillFactory.getSkill(5310006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getAttackX(); } bx = SkillFactory.getSkill(5321009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; ignoreTargetDEF += eff.getIgnoreMob(); } break; case 3001: case 3100: case 3110: case 3111: case 3112: mpRecoverProp = 100; bx = SkillFactory.getSkill(31000003); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getHpR(); } bx = SkillFactory.getSkill(31100007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(31000004, (int) eff.getDAMRate()); damageIncrease.put(31001006, (int) eff.getDAMRate()); damageIncrease.put(31001007, (int) eff.getDAMRate()); damageIncrease.put(31001008, (int) eff.getDAMRate()); } bx = SkillFactory.getSkill(31100005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(31100010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(31000004, (int) eff.getX()); damageIncrease.put(31001006, (int) eff.getX()); damageIncrease.put(31001007, (int) eff.getX()); damageIncrease.put(31001008, (int) eff.getX()); } bx = SkillFactory.getSkill(31111007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; } bx = SkillFactory.getSkill(31110008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dodgeChance += eff.getX(); // HACK: shouldn't be here hpRecoverPercent += eff.getY(); hpRecoverProp += eff.getX(); //mpRecover += eff.getY(); // handle in takeDamage //mpRecoverProp += eff.getX(); } bx = SkillFactory.getSkill(31110009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mpRecover += 1; mpRecoverProp += eff.getProb(); } bx = SkillFactory.getSkill(31111006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getX() + 100.0) / 100.0; bossdam_r *= (eff.getX() + 100.0) / 100.0; crit_rate += eff.getY(); } bx = SkillFactory.getSkill(31121006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ignoreTargetDEF += bx.getEffect(bof).getIgnoreMob(); } bx = SkillFactory.getSkill(31120011); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(31000004, (int) eff.getX()); damageIncrease.put(31001006, (int) eff.getX()); damageIncrease.put(31001007, (int) eff.getX()); damageIncrease.put(31001008, (int) eff.getX()); } bx = SkillFactory.getSkill(31120008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getAttackX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(31120010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_wdef += bx.getEffect(bof).getT(); } bx = SkillFactory.getSkill(30010112); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); bossdam_r += eff.getBossDamage(); mpRecover += eff.getX(); mpRecoverProp += eff.getBossDamage(); //yes } bx = SkillFactory.getSkill(30010185); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); chra.getTrait(MapleTraitType.will).addLocalExp(GameConstants.getTraitExpNeededForLevel(eff.getY())); chra.getTrait(MapleTraitType.charisma).addLocalExp(GameConstants.getTraitExpNeededForLevel(eff.getZ())); } bx = SkillFactory.getSkill(30010111); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); hpRecoverPercent += eff.getX(); hpRecoverProp += eff.getProb(); //yes } bx = SkillFactory.getSkill(31110009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localmaxmp += eff.getMaxDemonFury(); //yes } break; case 3002: case 3600: case 3610: case 3611: case 3612: { bx = SkillFactory.getSkill(30020234); //Lateral 1 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } bx = SkillFactory.getSkill(36000004); //Lateral 2 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getZ(); percent_mp += bx.getEffect(bof).getS(); } bx = SkillFactory.getSkill(36100007); //Lateral 3 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getS(); percent_mp += bx.getEffect(bof).getS(); } bx = SkillFactory.getSkill(36110007); //Lateral 4 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getS(); percent_mp += bx.getEffect(bof).getS(); } bx = SkillFactory.getSkill(36120010); //Lateral 5 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getS(); percent_mp += bx.getEffect(bof).getS(); } bx = SkillFactory.getSkill(36120045); //Lateral 5 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { targetPlus += bx.getEffect(bof).gettargetPlus(); } break; } case 6000: case 6100: case 6110: case 6111: case 6112: { bx = SkillFactory.getSkill(61100007); //Inner Blaze bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } bx = SkillFactory.getSkill(61110007); //Adv Inner Blade bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } bx = SkillFactory.getSkill(60000222); //Iron Will bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } break; } case 510: case 511: case 512: { bx = SkillFactory.getSkill(5100009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } break; } case 1510: case 1511: case 1512: { bx = SkillFactory.getSkill(15100007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } break; } case 508: case 570: case 571: case 572: { // Jett bx = SkillFactory.getSkill(5080000); // Comet Booster bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); accuracy += eff.getAccX(); jump += eff.getPassiveJump(); speed += eff.getSpeedMax(); // TODO: split speed max and speed. (speed have a limit, while speedMax will add to the max) } // TODO: research more on percentage hp/mp and stats, which doesn't take effect to note. bx = SkillFactory.getSkill(5080004); // Shadow Heart bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); passive_sharpeye_min_percent += eff.getCriticalMin(); } // 5081010, 5081011: Hidden if (chra.getJob() >= 570) { bx = SkillFactory.getSkill(5700003); // Physical Training bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); } } if (chra.getJob() >= 571) { bx = SkillFactory.getSkill(5710004); // High Life bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_wdef += eff.getWDEFRate(); percent_mdef += eff.getMDEFRate(); add_hp += eff.getMaxHpX(); add_mp += eff.getMaxMpX(); } bx = SkillFactory.getSkill(5710005); // Cutting Edge bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); ignoreTargetDEF += eff.getIgnoreMob(); } } if (chra.getJob() == 572) { bx = SkillFactory.getSkill(5720008); // Collateral Damage bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); passive_sharpeye_min_percent += eff.getCriticalMin(); passive_sharpeye_percent += eff.getCriticalMax(); bossdam_r += eff.getBossDamage(); } // TODO: 5721009, 5720012(Counterattack) } break; } case 400: // Thief case 410: // Assassin case 411: // Hermit case 412: // Night Lord case 420: // Bandit case 421: // Chief Bandit case 422: { // Shadower bx = SkillFactory.getSkill(4001005); // Haste bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); speed += eff.getSpeedMax(); } // 4000010: Magic Theft, invisible. if (chra.getJob() >= 410 && chra.getJob() <= 412) { bx = SkillFactory.getSkill(4100007); // Physical Training bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localluk += eff.getLukX(); localdex += eff.getDexX(); } } if (chra.getJob() == 411 || chra.getJob() == 412) { bx = SkillFactory.getSkill(4110008); // Enveloping Darkness bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getPercentHP(); ASR += eff.getASRRate(); TER += eff.getTERRate(); } bx = SkillFactory.getSkill(4110012); // Expert Throwing Star Handling bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(4001344, eff.getDAMRate()); damageIncrease.put(4101008, eff.getDAMRate()); damageIncrease.put(4101009, eff.getDAMRate()); damageIncrease.put(4101010, eff.getDAMRate()); } bx = SkillFactory.getSkill(4110014); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); RecoveryUP += eff.getX() - 100; } } if (chra.getJob() == 412) { bx = SkillFactory.getSkill(4121014); // Dark Harmony bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); ignoreTargetDEF += eff.getIgnoreMob(); } } bx = SkillFactory.getSkill(4200006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getPercentHP(); ASR += eff.getASRRate(); TER += eff.getTERRate(); } bx = SkillFactory.getSkill(4210000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_wdef += eff.getX(); percent_mdef += eff.getX(); } break; } case 431: // Blade Acolyte case 432: // Blade Specialist case 433: // Blade Lord case 434: { // Blade Master bx = SkillFactory.getSkill(4001006); // Haste bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); speed += eff.getSpeedMax(); } bx = SkillFactory.getSkill(4310004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getPercentHP(); ASR += eff.getASRRate(); TER += eff.getTERRate(); } bx = SkillFactory.getSkill(4341006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_wdef += eff.getWDEFRate(); percent_mdef += eff.getMDEFRate(); } break; } case 100: case 110: case 111: case 112: case 120: case 121: case 122: case 130: case 131: case 132: { bx = SkillFactory.getSkill(1000006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } bx = SkillFactory.getSkill(1210001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_wdef += eff.getX(); percent_mdef += eff.getX(); } bx = SkillFactory.getSkill(1220005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_wdef += bx.getEffect(bof).getT(); } bx = SkillFactory.getSkill(1220010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { trueMastery += bx.getEffect(bof).getMastery(); } bx = SkillFactory.getSkill(1310000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { TER += bx.getEffect(bof).getX(); } break; } case 322: { // Crossbowman bx = SkillFactory.getSkill(3220004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(3220009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getPercentHP(); ignoreTargetDEF += eff.getIgnoreMob(); } bx = SkillFactory.getSkill(3220005); bof = chra.getTotalSkillLevel(bx); if (bof > 0 && chra.getBuffedValue(MapleBuffStat.SPIRIT_LINK) != null) { eff = bx.getEffect(bof); percent_hp += eff.getX(); dam_r *= (eff.getDamage() + 100.0) / 100.0; bossdam_r *= (eff.getDamage() + 100.0) / 100.0; } break; } case 312: { // Bowmaster bx = SkillFactory.getSkill(3120005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(3120011); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_hp += eff.getPercentHP(); ignoreTargetDEF += eff.getIgnoreMob(); } bx = SkillFactory.getSkill(3120006); bof = chra.getTotalSkillLevel(bx); if (bof > 0 && chra.getBuffedValue(MapleBuffStat.SPIRIT_LINK) != null) { eff = bx.getEffect(bof); percent_hp += eff.getX(); dam_r *= (eff.getDamage() + 100.0) / 100.0; bossdam_r *= (eff.getDamage() + 100.0) / 100.0; } break; } case 3510: case 3511: case 3512: { bx = SkillFactory.getSkill(35100000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getAttackX(); } bx = SkillFactory.getSkill(35120000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { trueMastery += bx.getEffect(bof).getMastery(); } break; } case 3211: case 3212: { bx = SkillFactory.getSkill(32110000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ASR += bx.getEffect(bof).getASRRate(); TER += bx.getEffect(bof).getTERRate(); } bx = SkillFactory.getSkill(32110001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(32120000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { magic += bx.getEffect(bof).getMagicX(); } bx = SkillFactory.getSkill(32120001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } bx = SkillFactory.getSkill(32120009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } break; } case 3300: case 3310: case 3311: case 3312: { bx = SkillFactory.getSkill(33120000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(33110000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDamage() + 100.0) / 100.0; bossdam_r *= (eff.getDamage() + 100.0) / 100.0; } bx = SkillFactory.getSkill(33120010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); ignoreTargetDEF += eff.getIgnoreMob(); dodgeChance += eff.getER(); } bx = SkillFactory.getSkill(32110001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; } break; } case 2200: case 2210: case 2211: case 2212: case 2213: case 2214: case 2215: case 2216: case 2217: case 2218: { magic += chra.getTotalSkillLevel(SkillFactory.getSkill(22000000)); bx = SkillFactory.getSkill(22150000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mpconPercent += eff.getX() - 100; dam_r *= eff.getY() / 100.0; bossdam_r *= eff.getY() / 100.0; } bx = SkillFactory.getSkill(22160000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDamage() + 100.0) / 100.0; bossdam_r *= (eff.getDamage() + 100.0) / 100.0; } bx = SkillFactory.getSkill(22170001); // magic mastery, this is an invisible skill bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); magic += eff.getX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } break; } case 2112: { bx = SkillFactory.getSkill(21120001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } break; } case 4100: // Hayato case 4110: case 4111: case 4112: /* if (chra.getJob() >= 4111) { bx = SkillFactory.getSkill(41110006);// Willow Dodge bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dodgeChance += bx.getEffect(bof).getER(); dam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; bossdam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; } } * */ if (chra.getJob() >= 4111) { bx = SkillFactory.getSkill(41120006);// Willow Dodge 2 bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dodgeChance += eff.getPercentAvoid();//dodgeChance += eff.getER(); } } if (chra.getJob() >= 4110) { bx = SkillFactory.getSkill(41100006); // Unfaltering Blade bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); accuracy += eff.getX(); passive_sharpeye_percent += eff.getCriticalMax(); passive_sharpeye_min_percent += eff.getCriticalMin(); } } if (chra.getJob() >= 4100) { bx = SkillFactory.getSkill(41000003); // Center Ki bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); } } break; } bx = SkillFactory.getSkill(80000000); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); localint_ += eff.getIntX(); localluk += eff.getLukX(); percent_hp += eff.getHpR(); percent_mp += eff.getMpR(); } bx = SkillFactory.getSkill(80000001); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); bossdam_r += eff.getBossDamage(); } bx = SkillFactory.getSkill(80001040); bof = chra.getSkillLevel(bx); if (bof > 0) { expBuff *= (bx.getEffect(bof).getEXPRate() + 100.0) / 100.0; } if (GameConstants.isAdventurer(chra.getJob())) { bx = SkillFactory.getSkill(74); bof = chra.getSkillLevel(bx); if (bof > 0) { levelBonus += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(80); bof = chra.getSkillLevel(bx); if (bof > 0) { levelBonus += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(10074); bof = chra.getSkillLevel(bx); if (bof > 0) { levelBonus += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(10080); bof = chra.getSkillLevel(bx); if (bof > 0) { levelBonus += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(110); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); localint_ += eff.getIntX(); localluk += eff.getLukX(); percent_hp += eff.getHpR(); percent_mp += eff.getMpR(); } bx = SkillFactory.getSkill(10110); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); localint_ += eff.getIntX(); localluk += eff.getLukX(); percent_hp += eff.getHpR(); percent_mp += eff.getMpR(); } } bx = SkillFactory.getSkill(GameConstants.getBOF_ForJob(chra.getJob())); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getX(); magic += eff.getY(); accuracy += eff.getX(); } bx = SkillFactory.getSkill(GameConstants.getEmpress_ForJob(chra.getJob())); bof = chra.getSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getX(); magic += eff.getY(); accuracy += eff.getZ(); } switch (chra.getJob()) { case 210: case 211: case 212: { // IL bx = SkillFactory.getSkill(2100007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { localint_ += bx.getEffect(bof).getIntX(); } bx = SkillFactory.getSkill(2110000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dotTime += eff.getX(); dot += eff.getZ(); } bx = SkillFactory.getSkill(2110001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mpconPercent += eff.getX() - 100; dam_r *= eff.getY() / 100.0; bossdam_r *= eff.getY() / 100.0; } bx = SkillFactory.getSkill(2121003); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(2111003, (int) eff.getX()); } bx = SkillFactory.getSkill(2120009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); magic += eff.getMagicX(); BuffUP_Skill += eff.getX(); } bx = SkillFactory.getSkill(2121005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { TER += bx.getEffect(bof).getTERRate(); } bx = SkillFactory.getSkill(2121009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { magic += bx.getEffect(bof).getMagicX(); } bx = SkillFactory.getSkill(2120010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; bossdam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; ignoreTargetDEF += eff.getIgnoreMob(); } break; } case 220: case 221: case 222: { // IL bx = SkillFactory.getSkill(2200007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { localint_ += bx.getEffect(bof).getIntX(); } bx = SkillFactory.getSkill(2210000); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dot += bx.getEffect(bof).getZ(); } bx = SkillFactory.getSkill(2210001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mpconPercent += eff.getX() - 100; dam_r *= eff.getY() / 100.0; bossdam_r *= eff.getY() / 100.0; } bx = SkillFactory.getSkill(2220009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); magic += eff.getMagicX(); BuffUP_Skill += eff.getX(); } bx = SkillFactory.getSkill(2221005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { TER += bx.getEffect(bof).getTERRate(); } bx = SkillFactory.getSkill(2221009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { magic += bx.getEffect(bof).getMagicX(); } bx = SkillFactory.getSkill(2220010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; bossdam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; ignoreTargetDEF += eff.getIgnoreMob(); } break; } case 1211: case 1212: { // flame bx = SkillFactory.getSkill(12110001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mpconPercent += eff.getX() - 100; dam_r *= eff.getY() / 100.0; bossdam_r *= eff.getY() / 100.0; } bx = SkillFactory.getSkill(12111004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { TER += bx.getEffect(bof).getTERRate(); } break; } case 230: case 231: case 232: { // Bishop bx = SkillFactory.getSkill(2300007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { localint_ += bx.getEffect(bof).getIntX(); } bx = SkillFactory.getSkill(2310008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { crit_rate += bx.getEffect(bof).getCr(); } bx = SkillFactory.getSkill(2320010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); magic += eff.getMagicX(); BuffUP_Skill += eff.getX(); } bx = SkillFactory.getSkill(2321010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { magic += bx.getEffect(bof).getMagicX(); } bx = SkillFactory.getSkill(2320005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ASR += bx.getEffect(bof).getASRRate(); } bx = SkillFactory.getSkill(2320011); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; bossdam_r *= (eff.getX() * eff.getY() + 100.0) / 100.0; ignoreTargetDEF += eff.getIgnoreMob(); } break; } case 2002: case 2300: case 2310: case 2311: case 2312: { bx = SkillFactory.getSkill(20021110); bof = chra.getSkillLevel(bx); if (bof > 0) { expBuff *= (bx.getEffect(bof).getEXPRate() + 100.0) / 100.0; } bx = SkillFactory.getSkill(20020112); bof = chra.getSkillLevel(bx); if (bof > 0) { chra.getTrait(MapleTraitType.charm).addLocalExp(GameConstants.getTraitExpNeededForLevel(30)); } bx = SkillFactory.getSkill(23000001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } bx = SkillFactory.getSkill(23100008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(23110004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getProb(); } bx = SkillFactory.getSkill(23110004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(23101001, (int) bx.getEffect(bof).getDAMRate()); } bx = SkillFactory.getSkill(23121004); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getProb(); } bx = SkillFactory.getSkill(23120009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getX(); } bx = SkillFactory.getSkill(23120010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ignoreTargetDEF += bx.getEffect(bof).getX(); //or should we do 100? } bx = SkillFactory.getSkill(23120011); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(23101001, (int) bx.getEffect(bof).getDAMRate()); } bx = SkillFactory.getSkill(23120012); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { watk += bx.getEffect(bof).getAttackX(); } break; } case 1300: case 1310: case 1311: case 1312: { bx = SkillFactory.getSkill(13000001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { defRange += bx.getEffect(bof).getRange(); } bx = SkillFactory.getSkill(13110008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } bx = SkillFactory.getSkill(13110003); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } break; } case 300: case 310: case 311: case 312: { bx = SkillFactory.getSkill(3000002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { defRange += bx.getEffect(bof).getRange(); } bx = SkillFactory.getSkill(3100006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(3001004, eff.getX()); damageIncrease.put(3001005, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(3110007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } bx = SkillFactory.getSkill(3120005); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } break; } case 320: case 321: case 322: { bx = SkillFactory.getSkill(3000002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { defRange += bx.getEffect(bof).getRange(); } bx = SkillFactory.getSkill(3200006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(3001004, eff.getX()); damageIncrease.put(3001005, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(3220010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(3211006, bx.getEffect(bof).getDamage() - 150); } bx = SkillFactory.getSkill(3210007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } break; } case 422: { bx = SkillFactory.getSkill(4221007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Savage Blow, Steal, and Assaulter eff = bx.getEffect(bof); damageIncrease.put(4201005, (int) eff.getDAMRate()); damageIncrease.put(4201004, (int) eff.getDAMRate()); damageIncrease.put(4211002, (int) eff.getDAMRate()); } bx = SkillFactory.getSkill(4210012); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); mesoBuff *= (eff.getMesoRate() + 100.0) / 100.0; pickRate += eff.getU(); mesoGuard -= eff.getV(); mesoGuardMeso -= eff.getW(); damageIncrease.put(4211006, eff.getX()); } break; } case 433: case 434: { bx = SkillFactory.getSkill(4330007); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); hpRecoverProp += eff.getProb(); hpRecoverPercent += eff.getX(); } bx = SkillFactory.getSkill(4341002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Fatal Blow, Slash Storm, Tornado Spin, Bloody Storm, Upper Stab, and Flying Assaulter eff = bx.getEffect(bof); damageIncrease.put(4311002, (int) eff.getDAMRate()); damageIncrease.put(4311003, (int) eff.getDAMRate()); damageIncrease.put(4321000, (int) eff.getDAMRate()); damageIncrease.put(4321001, (int) eff.getDAMRate()); damageIncrease.put(4331000, (int) eff.getDAMRate()); damageIncrease.put(4331004, (int) eff.getDAMRate()); damageIncrease.put(4331005, (int) eff.getDAMRate()); } bx = SkillFactory.getSkill(4341006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { dodgeChance += bx.getEffect(bof).getER(); } break; } case 2110: case 2111: case 2112: { // Aran bx = SkillFactory.getSkill(21101006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; } bx = SkillFactory.getSkill(21110002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(21000004, bx.getEffect(bof).getW()); } bx = SkillFactory.getSkill(21111010); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ignoreTargetDEF += bx.getEffect(bof).getIgnoreMob(); } bx = SkillFactory.getSkill(21120002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { damageIncrease.put(21100007, bx.getEffect(bof).getZ()); } bx = SkillFactory.getSkill(21120011); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(21100002, (int) eff.getDAMRate()); damageIncrease.put(21110003, (int) eff.getDAMRate()); } break; } case 3511: case 3512: { bx = SkillFactory.getSkill(35110014); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //ME-07 Drillhands, Atomic Hammer eff = bx.getEffect(bof); damageIncrease.put(35001003, (int) eff.getDAMRate()); damageIncrease.put(35101003, (int) eff.getDAMRate()); } bx = SkillFactory.getSkill(35121006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Satellite eff = bx.getEffect(bof); damageIncrease.put(35111001, (int) eff.getDAMRate()); // damageIncrease.put(35111009, (int) eff.getDAMRate()); // damageIncrease.put(35111010, (int) eff.getDAMRate()); } bx = SkillFactory.getSkill(35120001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Satellite eff = bx.getEffect(bof); damageIncrease.put(35111005, eff.getX()); damageIncrease.put(35111011, eff.getX()); damageIncrease.put(35121009, eff.getX()); damageIncrease.put(35121010, eff.getX()); damageIncrease.put(35121011, eff.getX()); BuffUP_Summon += eff.getY(); } break; } case 110: case 111: case 112: { bx = SkillFactory.getSkill(1100009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(1001004, eff.getX()); damageIncrease.put(1001005, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(1110009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= eff.getDamage() / 100.0; bossdam_r *= eff.getDamage() / 100.0; } bx = SkillFactory.getSkill(1120012); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ignoreTargetDEF += bx.getEffect(bof).getIgnoreMob(); } bx = SkillFactory.getSkill(1120013); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getAttackX(); damageIncrease.put(1100002, (int) eff.getDamage()); } break; } case 120: case 121: case 122: { bx = SkillFactory.getSkill(1200009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(1001004, eff.getX()); damageIncrease.put(1001005, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(1220006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { ASR += bx.getEffect(bof).getASRRate(); TER += bx.getEffect(bof).getTERRate(); } break; } case 511: case 512: { bx = SkillFactory.getSkill(5110008); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Backspin Blow, Double Uppercut, and Corkscrew Blow eff = bx.getEffect(bof); damageIncrease.put(5101002, eff.getX()); damageIncrease.put(5101003, eff.getY()); damageIncrease.put(5101004, eff.getZ()); } break; } case 520: case 521: case 522: { bx = SkillFactory.getSkill(5220001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { //Flamethrower and Ice Splitter eff = bx.getEffect(bof); damageIncrease.put(5211004, (int) eff.getDamage()); damageIncrease.put(5211005, (int) eff.getDamage()); } break; } case 130: case 131: case 132: { bx = SkillFactory.getSkill(1300009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(1001004, eff.getX()); damageIncrease.put(1001005, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(1310009); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); crit_rate += eff.getCr(); passive_sharpeye_min_percent += eff.getCriticalMin(); hpRecoverProp += eff.getProb(); hpRecoverPercent += eff.getX(); } bx = SkillFactory.getSkill(1320006); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); dam_r *= (eff.getDamage() + 100.0) / 100.0; bossdam_r *= (eff.getDamage() + 100.0) / 100.0; } break; } case 1400: case 1410: case 1411: case 1412: { bx = SkillFactory.getSkill(14110003); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); RecoveryUP += eff.getX() - 100; BuffUP += eff.getY() - 100; } bx = SkillFactory.getSkill(14000001); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { defRange += bx.getEffect(bof).getRange(); } break; } case 5000: // Mihile 0 case 5100: // Mihile 1 case 5110: // Mihile 2 case 5111: // Mihile 3 case 5112: { // Mihile 4 // Mihile 1st Job Passive Skills bx = SkillFactory.getSkill(51000000); // Mihile || HP Boost bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_hp += bx.getEffect(bof).getPercentHP(); } bx = SkillFactory.getSkill(51000001); // Mihile || Soul Shield bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); percent_wdef += eff.getX(); percent_mdef += eff.getX(); } bx = SkillFactory.getSkill(51000002); // Mihile || Soul Devotion bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); accuracy += eff.getAccX(); speed += eff.getPassiveSpeed(); jump += eff.getPassiveJump(); } // Mihile 2nd Job Passive Skills bx = SkillFactory.getSkill(51100000); // Mihile || Physical Training bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); damageIncrease.put(5001002, eff.getX()); damageIncrease.put(5001003, eff.getY()); localstr += eff.getStrX(); localdex += eff.getDexX(); } bx = SkillFactory.getSkill(51120002); // Mihile || Final Attack && Advanced Final Attack bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += eff.getAttackX(); damageIncrease.put(51100002, (int) eff.getDamage()); } // Mihile 3rd Job Passive Skills bx = SkillFactory.getSkill(51110000); // Mihile || Self Recovery bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); hpRecoverProp += eff.getProb(); hpRecover += eff.getX(); mpRecoverProp += eff.getProb(); mpRecover += eff.getX(); } bx = SkillFactory.getSkill(51110001); // Mihile || Intense Focus bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); localstr += eff.getStrX(); // Add Attack Speed here } bx = SkillFactory.getSkill(51110002); // Mihile || Righteous Indignation bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); ASR += eff.getX(); percent_atk += eff.getX(); passive_sharpeye_min_percent += eff.getCriticalMin(); } // Mihile 4th Job Passive Skills bx = SkillFactory.getSkill(51120000); // Mihile || Combat Mastery bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); ignoreTargetDEF += eff.getIgnoreMob(); } bx = SkillFactory.getSkill(51120001); // Mihile || Expert Sword Mastery bof = chra.getTotalSkillLevel(bx); if (bof > 0) { eff = bx.getEffect(bof); watk += bx.getEffect(bof).getX(); trueMastery += eff.getMastery(); passive_sharpeye_min_percent += eff.getCriticalMin(); } bx = SkillFactory.getSkill(51120003); // Mihile || Soul Asylum bof = chra.getTotalSkillLevel(bx); if (bof > 0) { percent_wdef += bx.getEffect(bof).getT(); } break; } } if (GameConstants.isResist(chra.getJob())) { bx = SkillFactory.getSkill(30000002); bof = chra.getTotalSkillLevel(bx); if (bof > 0) { RecoveryUP += bx.getEffect(bof).getX() - 100; } } } private void handleHyperPassiveSkills(MapleCharacter chra) { int prefix = chra.getJob() * 10000; Skill bx; int bof; MapleStatEffect eff; for (int i = 30; i < 50; i++) { bx = SkillFactory.getSkill(prefix + i); bof = chra.getSkillLevel(bx); if (bx != null && bx.isHyper() && bof > 0) { eff = bx.getEffect(bof); if (eff != null) { switch (i) { case 30: localstr += eff.getStrX(); break; case 31: localdex += eff.getDexX(); break; case 32: localint_ += eff.getIntX(); break; case 33: localluk += eff.getLukX(); break; case 34: crit_rate += eff.getCr(); break; case 35: accuracy += eff.getAccR(); break; case 36: percent_hp += eff.getPercentHP(); break; case 37: percent_mp += eff.getPercentMP(); break; case 38: localmaxmp += eff.getMaxDemonFury(); break; case 39: wdef += eff.getWDEFX(); break; case 40: mdef += eff.getMDEFX(); break; case 41: speed += eff.getSpeed(); break; case 42: jump += eff.getJump(); break; } } } } for (int i = 30; i < 50; i++) { bx = SkillFactory.getSkill(prefix + i); bof = chra.getSkillLevel(bx); if (bx != null && bx.isHyper() && bof > 0) { eff = bx.getEffect(bof); String name = bx.getName(); if (eff != null && name != null) { int skill = GameConstants.findSkillByName(name.split(" - ")[0], prefix, 0); if (skill != 0) { Skill skil = SkillFactory.getSkill(skill); if (skil != null && chra.getSkillLevel(skil) > 0) { if (eff.getDAMRate() > 0) { //skil.getEffect(chra.getSkillLevel(skil)).setDAMRate(eff.getDAMRate()); } } } } } } } private void handleBuffStats(MapleCharacter chra) { MapleStatEffect eff = chra.getStatForBuff(MapleBuffStat.MONSTER_RIDING); if (eff != null && eff.getSourceId() == 33001001) { // jaguar crit_rate += eff.getW(); percent_hp += eff.getZ(); } Integer buff = chra.getBuffedValue(MapleBuffStat.DICE_ROLL); if (buff != null) { percent_wdef += GameConstants.getDiceStat(buff.intValue(), 2); percent_mdef += GameConstants.getDiceStat(buff.intValue(), 2); percent_hp += GameConstants.getDiceStat(buff.intValue(), 3); percent_mp += GameConstants.getDiceStat(buff.intValue(), 3); crit_rate += GameConstants.getDiceStat(buff.intValue(), 4); dam_r *= (GameConstants.getDiceStat(buff.intValue(), 5) + 100.0) / 100.0; bossdam_r *= (GameConstants.getDiceStat(buff.intValue(), 5) + 100.0) / 100.0; expBuff *= (GameConstants.getDiceStat(buff.intValue(), 6) + 100.0) / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.HP_BOOST_PERCENT); if (buff != null) { percent_hp += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.HAYATO3); if (buff != null) { percent_hp += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.HAYATO3); if (buff != null) { percent_mp += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.MP_BOOST_PERCENT); if (buff != null) { percent_mp += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.DEFENCE_BOOST_R); if (buff != null) { percent_wdef += buff.intValue(); percent_mdef += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ABNORMAL_STATUS_R); if (buff != null) { ASR += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ELEMENTAL_STATUS_R); if (buff != null) { TER += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.INFINITY); if (buff != null) { percent_matk += buff.intValue() - 1; } buff = chra.getBuffedValue(MapleBuffStat.ONYX_SHROUD); if (buff != null) { dodgeChance += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.PVP_DAMAGE); if (buff != null) { pvpDamage += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.PVP_ATTACK); if (buff != null) { pvpDamage += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.FELINE_BERSERK); if (buff != null) { percent_hp += buff.intValue(); } eff = chra.getStatForBuff(MapleBuffStat.BLUE_AURA); if (eff != null) { percent_wdef += eff.getZ() + eff.getY(); percent_mdef += eff.getZ() + eff.getY(); } buff = chra.getBuffedValue(MapleBuffStat.CONVERSION); if (buff != null) { percent_hp += buff.intValue(); } else { buff = chra.getBuffedValue(MapleBuffStat.MAXHP); if (buff != null) { percent_hp += buff.intValue(); } } buff = chra.getBuffedValue(MapleBuffStat.MAXMP); if (buff != null) { percent_mp += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.MP_BUFF); if (buff != null) { percent_mp += buff.intValue(); } buff = chra.getBuffedSkill_X(MapleBuffStat.BUFF_MASTERY); if (buff != null) { BuffUP_Skill += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.STR); if (buff != null) { localstr += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.DEX); if (buff != null) { localdex += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.INT); if (buff != null) { localint_ += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.LUK); if (buff != null) { localluk += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ANGEL_STAT); if (buff != null) { localstr += buff.intValue(); localdex += buff.intValue(); localint_ += buff.intValue(); localluk += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ENHANCED_WDEF); if (buff != null) { wdef += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ENHANCED_MDEF); if (buff != null) { mdef += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.WDEF); if (buff != null) { wdef += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.WDEF); if (buff != null) { mdef += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.MAPLE_WARRIOR); if (buff != null) { final double d = buff.doubleValue() / 100.0; localstr += d * str; //base only localdex += d * dex; localluk += d * luk; localint_ += d * int_; } buff = chra.getBuffedValue(MapleBuffStat.ECHO_OF_HERO); if (buff != null) { final double d = buff.doubleValue() / 100.0; watk += (int) (watk * d); magic += (int) (magic * d); } buff = chra.getBuffedValue(MapleBuffStat.ARAN_COMBO); if (buff != null) { watk += buff.intValue() / 10; } buff = chra.getBuffedValue(MapleBuffStat.MESOGUARD); if (buff != null) { mesoGuardMeso += buff.doubleValue(); } buff = chra.getBuffedValue(MapleBuffStat.EXPRATE); if (buff != null) { expBuff *= buff.doubleValue() / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.DROP_RATE); if (buff != null) { dropBuff *= buff.doubleValue() / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.ACASH_RATE); if (buff != null) { cashBuff *= buff.doubleValue() / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.MESO_RATE); if (buff != null) { mesoBuff *= buff.doubleValue() / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.MESOUP); if (buff != null) { mesoBuff *= buff.doubleValue() / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.ACC); if (buff != null) { accuracy += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.ANGEL_ACC); if (buff != null) { accuracy += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.INDIE_PAD); if (buff != null) { watk += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.INDIE_MAD); if (buff != null) { magic += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.WATK); if (buff != null) { watk += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.DAMAGE_R); if (buff != null) { crit_rate += buff.intValue(); dam_r *= (buff.intValue() + 100.0) / 100.0; bossdam_r *= (buff.intValue() + 100.0) / 100.0; } buff = chra.getBuffedValue(MapleBuffStat.ENHANCED_WATK); if (buff != null) { watk += buff.intValue(); } eff = chra.getStatForBuff(MapleBuffStat.ENERGY_CHARGE); if (eff != null) { watk += eff.getWatk(); accuracy += eff.getAcc(); } buff = chra.getBuffedValue(MapleBuffStat.MATK); if (buff != null) { magic += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.SPEED); if (buff != null) { speed += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.JUMP); if (buff != null) { jump += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.DASH_SPEED); if (buff != null) { speed += buff.intValue(); } buff = chra.getBuffedValue(MapleBuffStat.DASH_JUMP); if (buff != null) { jump += buff.intValue(); } eff = chra.getStatForBuff(MapleBuffStat.HIDDEN_POTENTIAL); if (eff != null) { crit_rate = 100; //INTENSE ASR = 100; //INTENSE wdef += eff.getX(); mdef += eff.getX(); watk += eff.getX(); magic += eff.getX(); } buff = chra.getBuffedValue(MapleBuffStat.DAMAGE_BUFF); if (buff != null) { dam_r *= (buff.doubleValue() + 100.0) / 100.0; bossdam_r *= (buff.doubleValue() + 100.0) / 100.0; } buff = chra.getBuffedSkill_Y(MapleBuffStat.FINAL_CUT); if (buff != null) { dam_r *= buff.doubleValue() / 100.0; bossdam_r *= buff.doubleValue() / 100.0; } buff = chra.getBuffedSkill_Y(MapleBuffStat.OWL_SPIRIT); if (buff != null) { dam_r *= buff.doubleValue() / 100.0; bossdam_r *= buff.doubleValue() / 100.0; } buff = chra.getBuffedSkill_X(MapleBuffStat.BERSERK_FURY); if (buff != null) { dam_r *= buff.doubleValue() / 100.0; bossdam_r *= buff.doubleValue() / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.BLESS); if (eff != null) { watk += eff.getX(); magic += eff.getY(); accuracy += eff.getV(); } buff = chra.getBuffedSkill_X(MapleBuffStat.CONCENTRATE); if (buff != null) { mpconReduce += buff.intValue(); } eff = chra.getStatForBuff(MapleBuffStat.HOLY_SHIELD); if (eff != null) { watk += eff.getX(); magic += eff.getY(); accuracy += eff.getV(); mpconReduce += eff.getMPConReduce(); } eff = chra.getStatForBuff(MapleBuffStat.MAGIC_RESISTANCE); if (eff != null) { ASR += eff.getX(); } eff = chra.getStatForBuff(MapleBuffStat.COMBO); buff = chra.getBuffedValue(MapleBuffStat.COMBO); if (eff != null && buff != null) { dam_r *= ((100.0 + ((eff.getV() + eff.getDAMRate()) * (buff.intValue() - 1))) / 100.0); bossdam_r *= ((100.0 + ((eff.getV() + eff.getDAMRate()) * (buff.intValue() - 1))) / 100.0); } eff = chra.getStatForBuff(MapleBuffStat.SUMMON); if (eff != null) { if (eff.getSourceId() == 35121010) { //amp dam_r *= (eff.getX() + 100.0) / 100.0; bossdam_r *= (eff.getX() + 100.0) / 100.0; } } eff = chra.getStatForBuff(MapleBuffStat.DARK_AURA); if (eff != null) { dam_r *= (eff.getX() + 100.0) / 100.0; bossdam_r *= (eff.getX() + 100.0) / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.BODY_BOOST); if (eff != null) { dam_r *= (eff.getV() + 100.0) / 100.0; bossdam_r *= (eff.getV() + 100.0) / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.BEHOLDER); if (eff != null) { trueMastery += eff.getMastery(); } eff = chra.getStatForBuff(MapleBuffStat.MECH_CHANGE); if (eff != null) { crit_rate += eff.getCr(); } eff = chra.getStatForBuff(MapleBuffStat.PYRAMID_PQ); if (eff != null && eff.getBerserk() > 0) { dam_r *= eff.getBerserk() / 100.0; bossdam_r *= eff.getBerserk() / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.WK_CHARGE); if (eff != null) { dam_r *= eff.getDamage() / 100.0; bossdam_r *= eff.getDamage() / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.PICKPOCKET); if (eff != null) { pickRate = eff.getProb(); } eff = chra.getStatForBuff(MapleBuffStat.DAMAGE_RATE); if (eff != null) { dam_r *= (eff.getDAMRate() + 100.0) / 100.0; bossdam_r *= (eff.getDAMRate() + 100.0) / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.LIGHTNING_CHARGE); if (eff != null) { dam_r *= eff.getDamage() / 100.0; bossdam_r *= eff.getDamage() / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.WIND_WALK); if (eff != null) { dam_r *= eff.getDamage() / 100.0; bossdam_r *= eff.getDamage() / 100.0; } eff = chra.getStatForBuff(MapleBuffStat.DIVINE_SHIELD); if (eff != null) { watk += eff.getEnhancedWatk(); } buff = chra.getBuffedSkill_Y(MapleBuffStat.DARKSIGHT); if (buff != null) { dam_r *= (buff.intValue() + 100.0) / 100.0; bossdam_r *= (buff.intValue() + 100.0) / 100.0; } buff = chra.getBuffedSkill_X(MapleBuffStat.ENRAGE); if (buff != null) { dam_r *= (buff.intValue() + 100.0) / 100.0; bossdam_r *= (buff.intValue() + 100.0) / 100.0; } buff = chra.getBuffedSkill_X(MapleBuffStat.COMBAT_ORDERS); if (buff != null) { combatOrders += buff.intValue(); } eff = chra.getStatForBuff(MapleBuffStat.SHARP_EYES); if (eff != null) { crit_rate += eff.getX(); passive_sharpeye_percent += eff.getCriticalMax(); } buff = chra.getBuffedValue(MapleBuffStat.CRITICAL_RATE_BUFF); if (buff != null) { crit_rate += buff.intValue(); } if (speed > 140) { speed = 140; } if (jump > 123) { jump = 123; } buff = chra.getBuffedValue(MapleBuffStat.MONSTER_RIDING); if (buff != null) { jump = 120; switch (buff.intValue()) { case 1: speed = 150; break; case 2: speed = 170; break; case 3: speed = 180; break; default: speed = 200; //lol break; } } eff = chra.getStatForBuff(MapleBuffStat.ATTACK); if (eff != null) { watk = Integer.MAX_VALUE; } } public boolean checkEquipLevels(final MapleCharacter chr, long gain) { if (chr.isClone()) { return false; } boolean changed = false; final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); List<Equip> all = new ArrayList<>(equipLevelHandling); for (Equip eq : all) { int lvlz = eq.getEquipLevel(); eq.setItemEXP(Math.min(eq.getItemEXP() + gain, Long.MAX_VALUE)); if (eq.getEquipLevel() > lvlz) { //lvlup for (int i = eq.getEquipLevel() - lvlz; i > 0; i--) { //now for the equipment increments... final Map<Integer, Map<String, Integer>> inc = ii.getEquipIncrements(eq.getItemId()); int extra = eq.getYggdrasilWisdom(); if (extra == 1) { inc.get(lvlz + i).put("STRMin", 1); inc.get(lvlz + i).put("STRMax", 3); } else if (extra == 2) { inc.get(lvlz + i).put("DEXMin", 1); inc.get(lvlz + i).put("DEXMax", 3); } else if (extra == 3) { inc.get(lvlz + i).put("INTMin", 1); inc.get(lvlz + i).put("INTMax", 3); } else if (extra == 4) { inc.get(lvlz + i).put("LUKMin", 1); inc.get(lvlz + i).put("LUKMax", 3); } if (inc != null && inc.containsKey(lvlz + i)) { //flair = 1 eq = ii.levelUpEquip(eq, inc.get(lvlz + i)); } //UGH, skillz if (GameConstants.getStatFromWeapon(eq.getItemId()) == null && GameConstants.getMaxLevel(eq.getItemId()) < (lvlz + i) && Math.random() < 0.1 && eq.getIncSkill() <= 0 && ii.getEquipSkills(eq.getItemId()) != null) { for (int zzz : ii.getEquipSkills(eq.getItemId())) { final Skill skil = SkillFactory.getSkill(zzz); if (skil != null && skil.canBeLearnedBy(chr.getJob())) { //dont go over masterlevel :D eq.setIncSkill(skil.getId()); chr.dropMessage(5, "Your skill has gained a levelup: " + skil.getName() + " +1"); } } } } changed = true; } chr.forceReAddItem(eq.copy(), MapleInventoryType.EQUIPPED); } if (changed) { chr.equipChanged(); chr.getClient().getSession().write(EffectPacket.showItemLevelupEffect()); chr.getMap().broadcastMessage(chr, EffectPacket.showForeignItemLevelupEffect(chr.getId()), false); } return changed; } public boolean checkEquipDurabilitys(final MapleCharacter chr, int gain) { return checkEquipDurabilitys(chr, gain, false); } public boolean checkEquipDurabilitys(final MapleCharacter chr, int gain, boolean aboveZero) { if (chr.isClone() || chr.inPVP()) { return true; } List<Equip> all = new ArrayList<>(durabilityHandling); for (Equip item : all) { if (item != null && ((item.getPosition() >= 0) == aboveZero)) { item.setDurability(item.getDurability() + gain); if (item.getDurability() < 0) { //shouldnt be less than 0 item.setDurability(0); } } } for (Equip eqq : all) { if (eqq != null && eqq.getDurability() == 0 && eqq.getPosition() < 0) { //> 0 went to negative if (chr.getInventory(MapleInventoryType.EQUIP).isFull()) { chr.getClient().getSession().write(InventoryPacket.getInventoryFull()); chr.getClient().getSession().write(InventoryPacket.getShowInventoryFull()); return false; } durabilityHandling.remove(eqq); final short pos = chr.getInventory(MapleInventoryType.EQUIP).getNextFreeSlot(); MapleInventoryManipulator.unequip(chr.getClient(), eqq.getPosition(), pos); } else if (eqq != null) { chr.forceReAddItem(eqq.copy(), MapleInventoryType.EQUIPPED); } } return true; } private void CalcPassive_SharpEye(final MapleCharacter player) { Skill critSkill; int critlevel; if (GameConstants.isDemonSlayer(player.getJob())) { critSkill = SkillFactory.getSkill(30010022); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { crit_rate += critSkill.getEffect(critlevel).getProb(); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } } else if (GameConstants.isMercedes(player.getJob())) { critSkill = SkillFactory.getSkill(20020022); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { crit_rate += critSkill.getEffect(critlevel).getProb(); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } } else if (GameConstants.isResist(player.getJob())) { critSkill = SkillFactory.getSkill(30000022); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { crit_rate += critSkill.getEffect(critlevel).getProb(); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } } switch (player.getJob()) { // Apply passive Critical bonus case 410: // Assasin case 411: // Hermit case 412: { // Night Lord critSkill = SkillFactory.getSkill(4100001); // Critical Throw critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 2412: { // Phantom critSkill = SkillFactory.getSkill(24120006); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); this.watk += critSkill.getEffect(critlevel).getAttackX(); } break; } case 1410: case 1411: case 1412: { // Night Walker critSkill = SkillFactory.getSkill(14100001); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 3100: case 3110: case 3111: case 3112: { critSkill = SkillFactory.getSkill(31100006); //TODO LEGEND, not final critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.watk += critSkill.getEffect(critlevel).getAttackX(); } break; } case 2300: case 2310: case 2311: case 2312: { critSkill = SkillFactory.getSkill(23000003); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 3210: case 3211: case 3212: { critSkill = SkillFactory.getSkill(32100006); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 434: { critSkill = SkillFactory.getSkill(4340010); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 520: case 521: case 522: { critSkill = SkillFactory.getSkill(5200007); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 1211: case 1212: { critSkill = SkillFactory.getSkill(12110000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 530: case 531: case 532: { critSkill = SkillFactory.getSkill(5300004); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getCr()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 510: case 511: case 512: { // Buccaner, Viper critSkill = SkillFactory.getSkill(5110000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) critSkill.getEffect(critlevel).getProb(); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } //final Skill critSkill2 = SkillFactory.getSkill(5100008); // final int critlevel2 = player.getTotalSkillLevel(critSkill); // if (critlevel2 > 0) { // this.passive_sharpeye_rate += (short) critSkill2.getEffect(critlevel2).getCr(); // this.passive_sharpeye_min_percent += critSkill2.getEffect(critlevel2).getCriticalMin(); // } return; } case 1511: case 1512: { critSkill = SkillFactory.getSkill(15110000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 2111: case 2112: { critSkill = SkillFactory.getSkill(21110000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) ((critSkill.getEffect(critlevel).getX() * critSkill.getEffect(critlevel).getY()) + critSkill.getEffect(critlevel).getCr()); } break; } case 300: case 310: case 311: case 312: case 320: case 321: case 322: { // Bowman critSkill = SkillFactory.getSkill(3000001); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 1300: case 1310: case 1311: case 1312: { // Bowman critSkill = SkillFactory.getSkill(13000000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } case 2214: case 2215: case 2216: case 2217: case 2218: { //Evan critSkill = SkillFactory.getSkill(22140000); critlevel = player.getTotalSkillLevel(critSkill); if (critlevel > 0) { this.crit_rate += (short) (critSkill.getEffect(critlevel).getProb()); this.passive_sharpeye_min_percent += critSkill.getEffect(critlevel).getCriticalMin(); } break; } } } private void CalcPassive_Mastery(final MapleCharacter player) { if (player.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -11) == null) { passive_mastery = 0; return; } final int skil; final MapleWeaponType weaponType = GameConstants.getWeaponType(player.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -11).getItemId()); boolean acc = true; switch (weaponType) { case BOW: skil = GameConstants.isKOC(player.getJob()) ? 13100000 : 3100000; break; case CLAW: skil = 4100000; break; case CANE: skil = player.getTotalSkillLevel(24120006) > 0 ? 24120006 : 24100004; break; case CANNON: skil = 5300005; break; case KATARA: case DAGGER: skil = player.getJob() >= 430 && player.getJob() <= 434 ? 4300000 : 4200000; break; case CROSSBOW: skil = GameConstants.isResist(player.getJob()) ? 33100000 : 3200000; break; case AXE1H: case BLUNT1H: skil = GameConstants.isResist(player.getJob()) ? 31100004 : (GameConstants.isKOC(player.getJob()) ? 11100000 : (player.getJob() > 112 ? 1200000 : 1100000)); //hero/pally break; case AXE2H: case SWORD1H: case SWORD2H: case BLUNT2H: skil = GameConstants.isKOC(player.getJob()) ? 11100000 : (player.getJob() > 112 ? 1200000 : 1100000); //hero/pally break; case POLE_ARM: skil = GameConstants.isAran(player.getJob()) ? 21100000 : 1300000; break; case SPEAR: skil = 1300000; break; case KNUCKLE: skil = GameConstants.isKOC(player.getJob()) ? 15100001 : 5100001; break; case GUN: skil = GameConstants.isResist(player.getJob()) ? 35100000 : (GameConstants.isJett(player.getJob()) ? 5700000 : 5200000); break; case DUAL_BOW: skil = 23100005; break; case WAND: case STAFF: acc = false; skil = GameConstants.isResist(player.getJob()) ? 32100006 : (player.getJob() <= 212 ? 2100006 : (player.getJob() <= 222 ? 2200006 : (player.getJob() <= 232 ? 2300006 : (player.getJob() <= 2000 ? 12100007 : 22120002)))); break; default: passive_mastery = 0; return; } if (player.getSkillLevel(skil) <= 0) { passive_mastery = 0; return; }// TODO: add job id check above skill, etc final MapleStatEffect eff = SkillFactory.getSkill(skil).getEffect(player.getTotalSkillLevel(skil)); if (acc) { accuracy += eff.getX(); if (skil == 35100000) { watk += eff.getX(); } } else { magic += eff.getX(); } crit_rate += eff.getCr(); passive_mastery = (byte) eff.getMastery(); trueMastery += eff.getMastery() + weaponType.getBaseMastery(); if (player.getJob() == 412) { final Skill bx = SkillFactory.getSkill(4120012); // Claw Expert final int bof = player.getTotalSkillLevel(bx); if (bof > 0) { final MapleStatEffect eff2 = bx.getEffect(bof); passive_mastery = (byte) eff2.getMastery(); // Override accuracy += eff2.getPercentAcc(); dodgeChance += eff2.getPercentAvoid(); watk += eff2.getX(); trueMastery -= eff.getMastery(); // - old trueMastery += eff2.getMastery(); // add new } } } private void calculateFame(final MapleCharacter player) { player.getTrait(MapleTraitType.charm).addLocalExp(player.getFame()); for (MapleTraitType t : MapleTraitType.values()) { player.getTrait(t).recalcLevel(); } } public final short passive_sharpeye_min_percent() { return passive_sharpeye_min_percent; } public final short passive_sharpeye_percent() { return passive_sharpeye_percent; } public final short passive_sharpeye_rate() { return crit_rate; } public final byte passive_mastery() { return passive_mastery; //* 5 + 10 for mastery % } public final void calculateMaxBaseDamage(final int watk, final int pvpDamage, MapleCharacter chra) { if (watk <= 0) { localmaxbasedamage = 1; localmaxbasepvpdamage = 1; } else { final Item weapon_item = chra.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -11); final Item weapon_item2 = chra.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -10); final int job = chra.getJob(); final MapleWeaponType weapon = weapon_item == null ? MapleWeaponType.NOT_A_WEAPON : GameConstants.getWeaponType(weapon_item.getItemId()); final MapleWeaponType weapon2 = weapon_item2 == null ? MapleWeaponType.NOT_A_WEAPON : GameConstants.getWeaponType(weapon_item2.getItemId()); int mainstat, secondarystat, mainstatpvp, secondarystatpvp; final boolean mage = (job >= 200 && job <= 232) || (job >= 1200 && job <= 1212) || (job >= 2200 && job <= 2218) || (job >= 3200 && job <= 3212); switch (weapon) { case BOW: case CROSSBOW: case GUN: mainstat = localdex; secondarystat = localstr; mainstatpvp = dex; secondarystatpvp = str; break; case DAGGER: case KATARA: case CLAW: case CANE: mainstat = localluk; secondarystat = localdex + localstr; mainstatpvp = luk; secondarystatpvp = dex + str; break; default: if (mage) { mainstat = localint_; secondarystat = localluk; mainstatpvp = int_; secondarystatpvp = luk; } else { mainstat = localstr; secondarystat = localdex; mainstatpvp = str; secondarystatpvp = dex; } break; } localmaxbasepvpdamage = weapon.getMaxDamageMultiplier() * (4 * mainstatpvp + secondarystatpvp) * (100.0f + (pvpDamage / 100.0f)); localmaxbasepvpdamageL = weapon.getMaxDamageMultiplier() * (4 * mainstat + secondarystat) * (100.0f + (pvpDamage / 100.0f)); if (weapon2 != MapleWeaponType.NOT_A_WEAPON && weapon_item != null && weapon_item2 != null) { Equip we1 = (Equip) weapon_item; Equip we2 = (Equip) weapon_item2; localmaxbasedamage = weapon.getMaxDamageMultiplier() * (4 * mainstat + secondarystat) * ((watk - (mage ? we2.getMatk() : we2.getWatk())) / 100.0f); localmaxbasedamage += weapon2.getMaxDamageMultiplier() * (4 * mainstat + secondarystat) * ((watk - (mage ? we1.getMatk() : we1.getWatk())) / 100.0f); } else { localmaxbasedamage = weapon.getMaxDamageMultiplier() * (4 * mainstat + secondarystat) * (watk / 100.0f); } } } public final float getHealHP() { return shouldHealHP; } public final float getHealMP() { return shouldHealMP; } public final void relocHeal(MapleCharacter chra) { if (chra.isClone()) { return; } final int playerjob = chra.getJob(); shouldHealHP = 10 + recoverHP; // Reset shouldHealMP = GameConstants.isDemonSlayer(chra.getJob()) ? 0 : (3 + recoverMP + (localint_ / 10)); // i think mpRecoverTime = 0; hpRecoverTime = 0; if (playerjob == 111 || playerjob == 112) { final Skill effect = SkillFactory.getSkill(1110000); // Improving MP Recovery final int lvl = chra.getSkillLevel(effect); if (lvl > 0) { MapleStatEffect eff = effect.getEffect(lvl); if (eff.getHp() > 0) { shouldHealHP += eff.getHp(); hpRecoverTime = 4000; } shouldHealMP += eff.getMp(); mpRecoverTime = 4000; } } else if (playerjob == 1111 || playerjob == 1112) { final Skill effect = SkillFactory.getSkill(11110000); // Improving MP Recovery final int lvl = chra.getSkillLevel(effect); if (lvl > 0) { shouldHealMP += effect.getEffect(lvl).getMp(); mpRecoverTime = 4000; } } else if (GameConstants.isMercedes(playerjob)) { final Skill effect = SkillFactory.getSkill(20020109); // Improving MP Recovery final int lvl = chra.getSkillLevel(effect); if (lvl > 0) { shouldHealHP += (effect.getEffect(lvl).getX() * localmaxhp) / 100; hpRecoverTime = 4000; shouldHealMP += (effect.getEffect(lvl).getX() * localmaxmp) / 100; mpRecoverTime = 4000; } } else if (GameConstants.isJett(playerjob) && playerjob != 508) { final Skill effect = SkillFactory.getSkill(5700005); // Perseverance final int lvl = chra.getSkillLevel(effect); if (lvl > 0) { final MapleStatEffect eff = effect.getEffect(lvl); shouldHealHP += eff.getX(); shouldHealMP += eff.getX(); hpRecoverTime = eff.getY(); mpRecoverTime = eff.getY(); } } else if (playerjob == 3111 || playerjob == 3112) { final Skill effect = SkillFactory.getSkill(31110009); // Improving MP Recovery final int lvl = chra.getSkillLevel(effect); if (lvl > 0) { shouldHealMP += effect.getEffect(lvl).getY(); mpRecoverTime = 4000; } } if (chra.getChair() != 0) { // Is sitting on a chair. shouldHealHP += 99; // Until the values of Chair heal has been fixed, shouldHealMP += 99; // MP is different here, if chair data MP = 0, heal + 1.5 } else if (chra.getMap() != null) { // Because Heal isn't multipled when there's a chair :) final float recvRate = chra.getMap().getRecoveryRate(); if (recvRate > 0) { shouldHealHP *= recvRate; shouldHealMP *= recvRate; } } } public final void connectData(final MaplePacketLittleEndianWriter mplew) { mplew.writeShort(str); mplew.writeShort(dex); mplew.writeShort(int_); mplew.writeShort(luk); mplew.writeInt(hp); mplew.writeInt(maxhp); mplew.writeInt(mp); mplew.writeInt(maxmp); } public final void zeroData(final MaplePacketLittleEndianWriter mplew, final MapleCharacter chr) { mplew.writeInt(0); mplew.write(0xFF); mplew.write(0); mplew.writeInt(maxhp); mplew.writeInt(maxmp); mplew.write(0); mplew.writeInt(chr.getSecondHair()); mplew.writeInt(chr.getSecondFace()); mplew.writeInt(maxhp); mplew.writeInt(maxmp); } private final static int[] allJobs = {0, 10000, 10000000, 20000000, 20010000, 20020000, 20030000, 20040000, 30000000, 30010000, 50000000}; public final static int[] pvpSkills = {1000007, 2000007, 3000006, 4000010, 5000006, 5010004, 11000006, 12000006, 13000005, 14000006, 15000005, 21000005, 22000002, 23000004, 31000005, 32000012, 33000004, 35000005}; public static int getSkillByJob(final int skillID, final int job) { //test return skillID + (GameConstants.getBeginnerJob((short) job) * 10000); } public final int getSkillIncrement(final int skillID) { if (skillsIncrement.containsKey(skillID)) { return skillsIncrement.get(skillID); } return 0; } public final int getElementBoost(final Element key) { if (elemBoosts.containsKey(key)) { return elemBoosts.get(key); } return 0; } public final int getDamageIncrease(final int key) { if (damageIncrease.containsKey(key)) { return damageIncrease.get(key) + damX; } return damX; } public final int getAccuracy() { return accuracy; } public void heal_noUpdate(MapleCharacter chra) { setHp(getCurrentMaxHp(), chra); setMp(getCurrentMaxMp(chra.getJob()), chra); } public void heal(MapleCharacter chra) { heal_noUpdate(chra); chra.updateSingleStat(MapleStat.HP, getCurrentMaxHp()); chra.updateSingleStat(MapleStat.MP, getCurrentMaxMp(chra.getJob())); } public Pair<Integer, Integer> handleEquipAdditions(MapleItemInformationProvider ii, MapleCharacter chra, boolean first_login, Map<Skill, SkillEntry> sData, final int itemId) { final List<Triple<String, String, String>> additions = ii.getEquipAdditions(itemId); if (additions == null) { return null; } int localmaxhp_x = 0, localmaxmp_x = 0; int skillid = 0, skilllevel = 0; String craft, job, level; for (final Triple<String, String, String> add : additions) { if (add.getMid().contains("con")) { continue; } final int right = Integer.parseInt(add.getRight()); switch (add.getLeft()) { case "elemboost": craft = ii.getEquipAddReqs(itemId, add.getLeft(), "craft"); if (add.getMid().equals("elemVol") && (craft == null || craft != null && chra.getTrait(MapleTraitType.craft).getLocalTotalExp() >= Integer.parseInt(craft))) { int value = Integer.parseInt(add.getRight().substring(1, add.getRight().length())); final Element key = Element.getFromChar(add.getRight().charAt(0)); if (elemBoosts.get(key) != null) { value += elemBoosts.get(key); } elemBoosts.put(key, value); } break; case "mobcategory": //skip the category, thinkings too expensive to have yet another Map<Integer, Integer> for damage calculations if (add.getMid().equals("damage")) { dam_r *= (right + 100.0) / 100.0; bossdam_r += (right + 100.0) / 100.0; } break; case "critical": // lv critical lvl? boolean canJob = false, canLevel = false; job = ii.getEquipAddReqs(itemId, add.getLeft(), "job"); if (job != null) { if (job.contains(",")) { final String[] jobs = job.split(","); for (final String x : jobs) { if (chra.getJob() == Integer.parseInt(x)) { canJob = true; } } } else { if (chra.getJob() == Integer.parseInt(job)) { canJob = true; } } } level = ii.getEquipAddReqs(itemId, add.getLeft(), "level"); if (level != null) { if (chra.getLevel() >= Integer.parseInt(level)) { canLevel = true; } } if ((job != null && canJob || job == null) && (level != null && canLevel || level == null)) { switch (add.getMid()) { case "prob": crit_rate += right; break; case "damage": passive_sharpeye_min_percent += right; passive_sharpeye_percent += right; //???CONFIRM - not sure if this is max or minCritDmg break; } } break; case "boss": // ignore prob, just add craft = ii.getEquipAddReqs(itemId, add.getLeft(), "craft"); if (add.getMid().equals("damage") && (craft == null || craft != null && chra.getTrait(MapleTraitType.craft).getLocalTotalExp() >= Integer.parseInt(craft))) { bossdam_r *= (right + 100.0) / 100.0; } break; case "mobdie": // lv, hpIncRatioOnMobDie, hpRatioProp, mpIncRatioOnMobDie, mpRatioProp, modify =D, don't need mob to die craft = ii.getEquipAddReqs(itemId, add.getLeft(), "craft"); if ((craft == null || craft != null && chra.getTrait(MapleTraitType.craft).getLocalTotalExp() >= Integer.parseInt(craft))) { switch (add.getMid()) { case "hpIncOnMobDie": hpRecover += right; hpRecoverProp += 5; break; case "mpIncOnMobDie": mpRecover += right; mpRecoverProp += 5; break; } } break; case "skill": // all these are additional skills if (first_login) { craft = ii.getEquipAddReqs(itemId, add.getLeft(), "craft"); if ((craft == null || craft != null && chra.getTrait(MapleTraitType.craft).getLocalTotalExp() >= Integer.parseInt(craft))) { switch (add.getMid()) { case "id": skillid = right; break; case "level": skilllevel = right; break; } } } break; case "hpmpchange": switch (add.getMid()) { case "hpChangerPerTime": recoverHP += right; break; case "mpChangerPerTime": recoverMP += right; break; } break; case "statinc": boolean canJobx = false, canLevelx = false; job = ii.getEquipAddReqs(itemId, add.getLeft(), "job"); if (job != null) { if (job.contains(",")) { final String[] jobs = job.split(","); for (final String x : jobs) { if (chra.getJob() == Integer.parseInt(x)) { canJobx = true; } } } else if (chra.getJob() == Integer.parseInt(job)) { canJobx = true; } } level = ii.getEquipAddReqs(itemId, add.getLeft(), "level"); if (level != null && chra.getLevel() >= Integer.parseInt(level)) { canLevelx = true; } if ((!canJobx && job != null) || (!canLevelx && level != null)) { continue; } if (itemId == 1142367) { final int day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK); if (day != 1 && day != 7) { continue; } } switch (add.getMid()) { case "incPAD": watk += right; break; case "incMAD": magic += right; break; case "incSTR": localstr += right; break; case "incDEX": localdex += right; break; case "incINT": localint_ += right; break; case "incLUK": localluk += right; break; case "incJump": jump += right; break; case "incMHP": localmaxhp_x += right; break; case "incMMP": localmaxmp_x += right; break; case "incPDD": wdef += right; break; case "incMDD": mdef += right; break; case "incACC": accuracy += right; break; case "incEVA": break; case "incSpeed": speed += right; break; case "incMMPr": percent_mp += right; break; } break; } } if (skillid != 0 && skilllevel != 0) { sData.put(SkillFactory.getSkill(skillid), new SkillEntry((byte) skilllevel, (byte) 0, -1)); } return new Pair<>(localmaxhp_x, localmaxmp_x); } public void handleItemOption(StructItemOption soc, MapleCharacter chra, boolean first_login, Map<Skill, SkillEntry> hmm) { localstr += soc.get("incSTR"); localdex += soc.get("incDEX"); localint_ += soc.get("incINT"); localluk += soc.get("incLUK"); accuracy += soc.get("incACC"); // incEVA -> increase dodge speed += soc.get("incSpeed"); jump += soc.get("incJump"); watk += soc.get("incPAD"); magic += soc.get("incMAD"); wdef += soc.get("incPDD"); mdef += soc.get("incMDD"); percent_str += soc.get("incSTRr"); percent_dex += soc.get("incDEXr"); percent_int += soc.get("incINTr"); percent_luk += soc.get("incLUKr"); percent_hp += soc.get("incMHPr"); percent_mp += soc.get("incMMPr"); percent_acc += soc.get("incACCr"); dodgeChance += soc.get("incEVAr"); percent_atk += soc.get("incPADr"); percent_matk += soc.get("incMADr"); percent_wdef += soc.get("incPDDr"); percent_mdef += soc.get("incMDDr"); crit_rate += soc.get("incCr"); bossdam_r *= (soc.get("incDAMr") + 100.0) / 100.0; if (soc.get("boss") <= 0) { dam_r *= (soc.get("incDAMr") + 100.0) / 100.0; } recoverHP += soc.get("RecoveryHP"); // This shouldn't be here, set 4 seconds. recoverMP += soc.get("RecoveryMP"); // This shouldn't be here, set 4 seconds. if (soc.get("HP") > 0) { // Should be heal upon attacking hpRecover += soc.get("HP"); hpRecoverProp += soc.get("prop"); } if (soc.get("MP") > 0 && !GameConstants.isDemonSlayer(chra.getJob())) { mpRecover += soc.get("MP"); mpRecoverProp += soc.get("prop"); } ignoreTargetDEF += soc.get("ignoreTargetDEF"); if (soc.get("ignoreDAM") > 0) { ignoreDAM += soc.get("ignoreDAM"); ignoreDAM_rate += soc.get("prop"); } incAllskill += soc.get("incAllskill"); if (soc.get("ignoreDAMr") > 0) { ignoreDAMr += soc.get("ignoreDAMr"); ignoreDAMr_rate += soc.get("prop"); } RecoveryUP += soc.get("RecoveryUP"); // only for hp items and skills passive_sharpeye_min_percent += soc.get("incCriticaldamageMin"); passive_sharpeye_percent += soc.get("incCriticaldamageMax"); TER += soc.get("incTerR"); // elemental resistance = avoid element damage from monster ASR += soc.get("incAsrR"); // abnormal status = disease if (soc.get("DAMreflect") > 0) { DAMreflect += soc.get("DAMreflect"); DAMreflect_rate += soc.get("prop"); } mpconReduce += soc.get("mpconReduce"); reduceCooltime += soc.get("reduceCooltime"); // in seconds incMesoProp += soc.get("incMesoProp"); // mesos + % dropBuff *= (100 + soc.get("incRewardProp")) / 100.0; // extra drop rate for item if (first_login && soc.get("skillID") > 0) { hmm.put(SkillFactory.getSkill(getSkillByJob(soc.get("skillID"), chra.getJob())), new SkillEntry((byte) 1, (byte) 0, -1)); } bossdam_r *= (soc.get("bdR") + 100.0) / 100.0; ignoreTargetDEF *= (soc.get("imdR") + 100.0) / 100.0; // TODO: Auto Steal potentials (modify handleSteal), potentials with invincible stuffs, abnormal status duration decrease, // poison, stun, etc (uses level field -> cast disease to mob/player), face? } public final void handleProfessionTool(final MapleCharacter chra) { if (chra.getProfessionLevel(92000000) > 0 || chra.getProfessionLevel(92010000) > 0) { final Iterator<Item> itera = chra.getInventory(MapleInventoryType.EQUIP).newList().iterator(); while (itera.hasNext()) { //goes to first harvesting tool and stops final Equip equip = (Equip) itera.next(); if (equip.getDurability() != 0 && (equip.getItemId() / 10000 == 150 && chra.getProfessionLevel(92000000) > 0) || (equip.getItemId() / 10000 == 151 && chra.getProfessionLevel(92010000) > 0)) { if (equip.getDurability() > 0) { durabilityHandling.add(equip); } harvestingTool = equip.getPosition(); break; } } } } public void recalcPVPRank(MapleCharacter chra) { this.pvpRank = 10; this.pvpExp = chra.getTotalBattleExp(); for (int i = 0; i < 10; i++) { if (pvpExp > GameConstants.getPVPExpNeededForLevel(i + 1)) { pvpRank--; pvpExp -= GameConstants.getPVPExpNeededForLevel(i + 1); } } } public int getHPPercent() { return (int) Math.ceil((hp * 100.0) / localmaxhp); } public final void init(MapleCharacter chra) { recalcLocalStats(chra); } public final int getStr() { return str; } public final int getDex() { return dex; } public final int getInt() { return int_; } public final int getLuk() { return luk; } public final int getHp() { return hp; } public final int getMp() { return mp; } public final int getMaxHp() { return maxhp; } public final int getMaxMp() { return maxmp; } public final void setStr(final short str, MapleCharacter chra) { this.str = str; recalcLocalStats(chra); } public final void setDex(final short dex, MapleCharacter chra) { this.dex = dex; recalcLocalStats(chra); } public final void setInt(final short int_, MapleCharacter chra) { this.int_ = int_; recalcLocalStats(chra); } public final void setLuk(final short luk, MapleCharacter chra) { this.luk = luk; recalcLocalStats(chra); } public final boolean setHp(final int newhp, MapleCharacter chra) { return setHp(newhp, false, chra); } public final boolean setHp(int newhp, boolean silent, MapleCharacter chra) { final int oldHp = hp; int thp = newhp; if (thp < 0) { thp = 0; } if (thp > localmaxhp) { thp = localmaxhp; } this.hp = thp; if (chra != null) { if (!silent) { chra.checkBerserk(); chra.updatePartyMemberHP(); } if (oldHp > hp && !chra.isAlive()) { chra.playerDead(); } } if (GameConstants.isDemonAvenger(chra.getJob())) { chra.getClient().getSession().write(JobPacket.AvengerPacket.giveAvengerHpBuff(hp)); } return hp != oldHp; } public final boolean setMp(final int newmp, final MapleCharacter chra) { final int oldMp = mp; int tmp = newmp; if (tmp < 0) { tmp = 0; } if (tmp > localmaxmp) { tmp = localmaxmp; } this.mp = tmp; return mp != oldMp; } public final void setMaxHp(final int hp, MapleCharacter chra) { this.maxhp = hp; recalcLocalStats(chra); } public final void setMaxMp(final int mp, MapleCharacter chra) { this.maxmp = mp; recalcLocalStats(chra); } public final void setInfo(final int maxhp, final int maxmp, final int hp, final int mp) { this.maxhp = maxhp; this.maxmp = maxmp; this.hp = hp; this.mp = mp; } public final int getTotalStr() { return localstr; } public final int getTotalDex() { return localdex; } public final int getTotalInt() { return localint_; } public final int getTotalLuk() { return localluk; } public final int getTotalWatk() { return watk; } public final int getTotalMagic() { return magic; } public final int getCurrentMaxHp() { return localmaxhp; } public final int getCurrentMaxMp(final int job) { if (GameConstants.isDemonSlayer(job)) { return GameConstants.getMPByJob(job); } else if (GameConstants.isZero(job)) { localmaxmp = 100; } return localmaxmp; } public final int getHands() { return hands; // Only used for stimulator/maker skills } public final float getCurrentMaxBaseDamage() { return localmaxbasedamage; } public final float getCurrentMaxBasePVPDamage() { return localmaxbasepvpdamage; } public final float getCurrentMaxBasePVPDamageL() { return localmaxbasepvpdamageL; } public final boolean isRangedJob(final int job) { return GameConstants.isJett(job) || GameConstants.isMercedes(job) || GameConstants.isCannon(job) || job == 400 || (job / 10 == 52) || (job / 100 == 3) || (job / 100 == 13) || (job / 100 == 14) || (job / 100 == 33) || (job / 100 == 35) || (job / 10 == 41); } }