PHP Code:
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 && chra.getAndroid() == 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();
switch (equip.getItemId()) {
case 1112127:
equippedWelcomeBackRing = true;
break;
case 1122017:
equippedFairy = 10;
break;
case 1122158:
equippedFairy = 5;
break;
case 1112594: // white angelic blessing
equippedSummon = 1085;
break;
case 1112585:
equippedSummon = 1085;
break;
case 1112586:
equippedSummon = 1087;
break;
case 1112663:
equippedSummon = 1179; // white angelic blessing
break;
default:
for (int eb_bonus : GameConstants.Equipments_Bonus) {
if (equip.getItemId() == eb_bonus) { // bonus exp : P ( ring exp)
equipmentBonusExp += GameConstants.Equipment_Bonus_EXP(eb_bonus);
break;
}
}
break;
}
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 (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) {
int[] potentials = {equip.getPotential1(), equip.getPotential2(), equip.getPotential3(), equip.getPotential4(), equip.getPotential5()};
for (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);
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
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 (expMod < 1.2 && (item.getItemId() == 5211071 || item.getItemId() == 5211072 || item.getItemId() == 5211073 || item.getItemId() == 5211074 || item.getItemId() == 5211075 || item.getItemId() == 5211076 || item.getItemId() == 5211067)) {
expMod = 1.2;
}
} else if (dropMod == 1 && item.getItemId() / 10000 == 536) {
if (item.getItemId() == 5360000 || item.getItemId() == 5360009 || item.getItemId() == 5360010 || item.getItemId() == 5360011 || item.getItemId() == 5360012 || item.getItemId() == 5360013 || item.getItemId() == 5360014 || item.getItemId() == 5360017 || item.getItemId() == 5360050 || item.getItemId() == 5360053 || item.getItemId() == 5360042 || item.getItemId() == 5360052) {
dropMod = 2;
}
} else if (levelBonus == 0 && item.getItemId() == 5590000) {
levelBonus = 5;
} else if (item.getItemId() == 5710000) {
questBonus = 2;
}
}
for (Item item : chra.getInventory(MapleInventoryType.ETC).list()) { //omfg;
switch (item.getItemId()) {
case 4030003:
pickupRange = Double.POSITIVE_INFINITY;
break;
case 4030004:
hasClone = true;
break;
case 4030005:
cashMod = 2;
break;
}
}
if (first_login && chra.getLevel() >= 30) { //yeah
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));
sData.put(SkillFactory.getSkill(1179 + 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));
// sData.put(SkillFactory.getSkill(getSkillByJob(1179, 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);
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);
passive_sharpeye_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();
passive_sharpeye_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(99999, Math.abs(Math.max(-99999, localmaxhp_)));
localmaxmp_ += Math.floor((percent_mp * localmaxmp_) / 100.0f);
localmaxmp_ += chra.getTrait(MapleTraitType.sense).getLevel() * 20;
localmaxmp = Math.min(99999, Math.abs(Math.max(-99999, 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:
passive_sharpeye_rate += eff.getProb();
passive_sharpeye_percent = 100;
break;
}
break;
}
}
eff = chra.getStatForBuff(MapleBuffStat.MORPH);
if (eff != null && eff.getSourceId() % 10000 == 1105) { //ice knight
localmaxhp = 99999;
localmaxmp = 99999;
}
}
chra.changeSkillLevel_Skip(sData, false);
if (GameConstants.isDemon(chra.getJob())) {
localmaxmp = GameConstants.getMPByJob(chra.getJob());
}
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();
}
}