Optimized equip levelup method + Ultra three snails feature

Fixed performance drop on the server when trying to level up equipments
which has high stats points. Added a flag enabling massive damages with
Three Snails skill.
This commit is contained in:
ronancpl
2017-06-02 18:52:39 -03:00
parent fee0aa7e39
commit 02cc9efb00
27 changed files with 213 additions and 149 deletions

View File

@@ -1,4 +1,4 @@
#Thu, 01 Jun 2017 21:33:39 -0300 #Fri, 02 Jun 2017 18:46:19 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=

Binary file not shown.

Binary file not shown.

BIN
dist/MapleSolaxia.jar vendored

Binary file not shown.

View File

@@ -274,4 +274,8 @@ Compilada uma nova tabela de EXP para equips no jogo.
Adicionado novo sistema de EXP e nivelamento para todos os equipamentos, para além daqueles de tipo Reverse e Timeless. Adicionado novo sistema de EXP e nivelamento para todos os equipamentos, para além daqueles de tipo Reverse e Timeless.
01 Junho 2017, 01 Junho 2017,
Consertadas mecânicas principais para deletar character, possivelmente eliminando quaisquer resíduos do mesmo da DB. Requer que ENABLE_PIC esteja ativado para funcionar. Consertadas mecânicas principais para deletar character, possivelmente eliminando quaisquer resíduos do mesmo da DB. Requer que ENABLE_PIC esteja ativado para funcionar.
02 Junho 2017,
Otimizado e corrigido problemas de queda de desempenho ao atribuir lvups a itens com stats muito elevados, que ocasionavam crashs no servidor.
Adicionado funcionalidade USE_ULTRA_THREE_SNAILS. Valor mostrado não é condizente com o dano contabilizado (motivo: client edit).

View File

@@ -12,16 +12,12 @@
</editor-bookmarks> </editor-bookmarks>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2"> <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group> <group>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/AllianceOperationHandler.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/2010007.js</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/GuildOperationHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/guild/MapleGuild.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/guild/MapleGuild.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/MapleServerHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/guild/MapleAlliance.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/guild/MapleAlliance.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/Server.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/scripting/npc/NPCConversationManager.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/handlers/login/CreateCharHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/handlers/login/DeleteCharHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleClient.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleClient.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file> <file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file>
</group> </group>

View File

@@ -61,6 +61,7 @@ import org.apache.mina.core.session.IoSession;
import client.inventory.MapleInventoryType; import client.inventory.MapleInventoryType;
import constants.ServerConstants; import constants.ServerConstants;
import scripting.AbstractPlayerInteraction;
import scripting.event.EventManager; import scripting.event.EventManager;
import scripting.npc.NPCConversationManager; import scripting.npc.NPCConversationManager;
import scripting.npc.NPCScriptManager; import scripting.npc.NPCScriptManager;
@@ -145,6 +146,10 @@ public class MapleClient {
public void setPlayer(MapleCharacter player) { public void setPlayer(MapleCharacter player) {
this.player = player; this.player = player;
} }
public AbstractPlayerInteraction getAbstractPlayerInteraction() {
return new AbstractPlayerInteraction(this);
}
public void sendCharList(int server) { public void sendCharList(int server) {
this.session.write(MaplePacketCreator.getCharList(this, server)); this.session.write(MaplePacketCreator.getCharList(this, server));

View File

@@ -48,6 +48,24 @@ public class Equip extends Item {
return value; return value;
} }
} }
private static enum StatUpgrade {
incDEX(0), incSTR(1), incINT(2), incLUK(3),
incMHP(4), incMMP(5), incPAD(6), incMAD(7),
incPDD(8), incMDD(9), incEVA(10), incACC(11),
incSpeed(12), incJump(13), incVicious(14), incSlot(15);
private int value = -1;
private StatUpgrade(int value) {
this.value = value;
}
private int getValue() {
return value;
}
}
private byte upgradeSlots; private byte upgradeSlots;
private byte level, flag, itemLevel; private byte level, flag, itemLevel;
private short str, dex, _int, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, vicious; private short str, dex, _int, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, vicious;
@@ -277,13 +295,10 @@ public class Equip extends Item {
private int randomizeStatUpgrade(int limit) { private int randomizeStatUpgrade(int limit) {
Map<Integer, Integer> pool = new HashMap<>(); Map<Integer, Integer> pool = new HashMap<>();
pool.put(0, 1); int top = Math.min(limit, ServerConstants.MAX_EQUIPMNT_LVLUP_STAT_GAIN);
pool.put(1, 1); pool.put(0, top);
for(int i = 2; i <= limit; i++) { for(int i = 1; i <= top; i++) {
for(int j = 0; j < i; j++) { pool.put(i, top - i + 1);
pool.put(j, pool.get(j) + 1);
}
pool.put(i, 1);
} }
int poolCount = 0; int poolCount = 0;
@@ -303,7 +318,7 @@ public class Equip extends Item {
return(stat); return(stat);
} }
private void getUnitStatUpgrade(List<Pair<String, Integer>> stats, String name, int curStat, boolean isAttribute) { private void getUnitStatUpgrade(List<Pair<StatUpgrade, Integer>> stats, StatUpgrade name, int curStat, boolean isAttribute) {
isUpgradeable = true; isUpgradeable = true;
int maxUpgrade = randomizeStatUpgrade((int)(1 + (curStat / getStatModifier(isAttribute)))); int maxUpgrade = randomizeStatUpgrade((int)(1 + (curStat / getStatModifier(isAttribute))));
@@ -312,118 +327,134 @@ public class Equip extends Item {
stats.add(new Pair<>(name, maxUpgrade)); stats.add(new Pair<>(name, maxUpgrade));
} }
private void getUnitSlotUpgrade(List<Pair<String, Integer>> stats, String name) { private void getUnitSlotUpgrade(List<Pair<StatUpgrade, Integer>> stats, StatUpgrade name) {
if(Math.random() < 0.1) { if(Math.random() < 0.1) {
stats.add(new Pair<>(name, 1)); // 10% success on getting a slot upgrade. stats.add(new Pair<>(name, 1)); // 10% success on getting a slot upgrade.
} }
} }
private void improveDefaultStats(List<Pair<String, Integer>> stats) { private void improveDefaultStats(List<Pair<StatUpgrade, Integer>> stats) {
if(dex > 0) getUnitStatUpgrade(stats, "incDEX", dex, true); if(dex > 0) getUnitStatUpgrade(stats, StatUpgrade.incDEX, dex, true);
if(str > 0) getUnitStatUpgrade(stats, "incSTR", str, true); if(str > 0) getUnitStatUpgrade(stats, StatUpgrade.incSTR, str, true);
if(_int > 0) getUnitStatUpgrade(stats, "incINT",_int, true); if(_int > 0) getUnitStatUpgrade(stats, StatUpgrade.incINT,_int, true);
if(luk > 0) getUnitStatUpgrade(stats, "incLUK", luk, true); if(luk > 0) getUnitStatUpgrade(stats, StatUpgrade.incLUK, luk, true);
if(hp > 0) getUnitStatUpgrade(stats, "incMHP", hp, false); if(hp > 0) getUnitStatUpgrade(stats, StatUpgrade.incMHP, hp, false);
if(mp > 0) getUnitStatUpgrade(stats, "incMMP", mp, false); if(mp > 0) getUnitStatUpgrade(stats, StatUpgrade.incMMP, mp, false);
if(watk > 0) getUnitStatUpgrade(stats, "incPAD", watk, false); if(watk > 0) getUnitStatUpgrade(stats, StatUpgrade.incPAD, watk, false);
if(matk > 0) getUnitStatUpgrade(stats, "incMAD", matk, false); if(matk > 0) getUnitStatUpgrade(stats, StatUpgrade.incMAD, matk, false);
if(wdef > 0) getUnitStatUpgrade(stats, "incPDD", wdef, false); if(wdef > 0) getUnitStatUpgrade(stats, StatUpgrade.incPDD, wdef, false);
if(mdef > 0) getUnitStatUpgrade(stats, "incMDD", mdef, false); if(mdef > 0) getUnitStatUpgrade(stats, StatUpgrade.incMDD, mdef, false);
if(avoid > 0) getUnitStatUpgrade(stats, "incEVA", avoid, false); if(avoid > 0) getUnitStatUpgrade(stats, StatUpgrade.incEVA, avoid, false);
if(acc > 0) getUnitStatUpgrade(stats, "incACC", acc, false); if(acc > 0) getUnitStatUpgrade(stats, StatUpgrade.incACC, acc, false);
if(speed > 0) getUnitStatUpgrade(stats, "incSpeed", speed, false); if(speed > 0) getUnitStatUpgrade(stats, StatUpgrade.incSpeed, speed, false);
if(jump > 0) getUnitStatUpgrade(stats, "incJump", jump, false); if(jump > 0) getUnitStatUpgrade(stats, StatUpgrade.incJump, jump, false);
} }
public void gainLevel(MapleClient c) { private void gainLevel(MapleClient c) {
List<Pair<String, Integer>> stats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel); List<Pair<StatUpgrade, Integer>> stats = new LinkedList<>();
if(isElemental) {
List<Pair<String, Integer>> elementalStats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel);
for(Pair<String, Integer> p: elementalStats) {
if(p.getRight() > 0) stats.add(new Pair(StatUpgrade.valueOf(p.getLeft()), p.getRight()));
}
}
if(!stats.isEmpty()) { if(!stats.isEmpty()) {
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) { if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, "incVicious"); if(vicious > 0) getUnitSlotUpgrade(stats, StatUpgrade.incVicious);
getUnitSlotUpgrade(stats, "incSlot"); getUnitSlotUpgrade(stats, StatUpgrade.incSlot);
} }
} }
else { else {
isUpgradeable = false; isUpgradeable = false;
do { improveDefaultStats(stats);
improveDefaultStats(stats); if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, StatUpgrade.incVicious);
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) { getUnitSlotUpgrade(stats, StatUpgrade.incSlot);
if(vicious > 0) getUnitSlotUpgrade(stats, "incVicious"); }
getUnitSlotUpgrade(stats, "incSlot");
if(isUpgradeable) {
while(stats.isEmpty()) {
improveDefaultStats(stats);
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, StatUpgrade.incVicious);
getUnitSlotUpgrade(stats, StatUpgrade.incSlot);
}
} }
} while(stats.isEmpty() && isUpgradeable); }
} }
itemLevel++; itemLevel++;
boolean gotVicious = false, gotSlot = false; boolean gotVicious = false, gotSlot = false;
String lvupStr = "'" + MapleItemInformationProvider.getInstance().getName(this.getItemId()) + "' is now level " + itemLevel + "! "; String lvupStr = "'" + MapleItemInformationProvider.getInstance().getName(this.getItemId()) + "' is now level " + itemLevel + "! ";
for (Pair<String, Integer> stat : stats) { for (Pair<StatUpgrade, Integer> stat : stats) {
switch (stat.getLeft()) { switch (stat.getLeft()) {
case "incDEX": case incDEX:
dex += stat.getRight(); dex += stat.getRight();
lvupStr += "+" + stat.getRight() + "DEX "; lvupStr += "+" + stat.getRight() + "DEX ";
break; break;
case "incSTR": case incSTR:
str += stat.getRight(); str += stat.getRight();
lvupStr += "+" + stat.getRight() + "STR "; lvupStr += "+" + stat.getRight() + "STR ";
break; break;
case "incINT": case incINT:
_int += stat.getRight(); _int += stat.getRight();
lvupStr += "+" + stat.getRight() + "INT "; lvupStr += "+" + stat.getRight() + "INT ";
break; break;
case "incLUK": case incLUK:
luk += stat.getRight(); luk += stat.getRight();
lvupStr += "+" + stat.getRight() + "LUK "; lvupStr += "+" + stat.getRight() + "LUK ";
break; break;
case "incMHP": case incMHP:
hp += stat.getRight(); hp += stat.getRight();
lvupStr += "+" + stat.getRight() + "HP "; lvupStr += "+" + stat.getRight() + "HP ";
break; break;
case "incMMP": case incMMP:
mp += stat.getRight(); mp += stat.getRight();
lvupStr += "+" + stat.getRight() + "MP "; lvupStr += "+" + stat.getRight() + "MP ";
break; break;
case "incPAD": case incPAD:
watk += stat.getRight(); watk += stat.getRight();
lvupStr += "+" + stat.getRight() + "WATK "; lvupStr += "+" + stat.getRight() + "WATK ";
break; break;
case "incMAD": case incMAD:
matk += stat.getRight(); matk += stat.getRight();
lvupStr += "+" + stat.getRight() + "MATK "; lvupStr += "+" + stat.getRight() + "MATK ";
break; break;
case "incPDD": case incPDD:
wdef += stat.getRight(); wdef += stat.getRight();
lvupStr += "+" + stat.getRight() + "WDEF "; lvupStr += "+" + stat.getRight() + "WDEF ";
break; break;
case "incMDD": case incMDD:
mdef += stat.getRight(); mdef += stat.getRight();
lvupStr += "+" + stat.getRight() + "MDEF "; lvupStr += "+" + stat.getRight() + "MDEF ";
break; break;
case "incEVA": case incEVA:
avoid += stat.getRight(); avoid += stat.getRight();
lvupStr += "+" + stat.getRight() + "AVOID "; lvupStr += "+" + stat.getRight() + "AVOID ";
break; break;
case "incACC": case incACC:
acc += stat.getRight(); acc += stat.getRight();
lvupStr += "+" + stat.getRight() + "ACC "; lvupStr += "+" + stat.getRight() + "ACC ";
break; break;
case "incSpeed": case incSpeed:
speed += stat.getRight(); speed += stat.getRight();
lvupStr += "+" + stat.getRight() + "SPEED "; lvupStr += "+" + stat.getRight() + "SPEED ";
break; break;
case "incJump": case incJump:
jump += stat.getRight(); jump += stat.getRight();
lvupStr += "+" + stat.getRight() + "JUMP "; lvupStr += "+" + stat.getRight() + "JUMP ";
break; break;
case "incVicious": case incVicious:
vicious -= stat.getRight(); vicious -= stat.getRight();
gotVicious = true; gotVicious = true;
break; break;
case "incSlot": case incSlot:
upgradeSlots += stat.getRight(); upgradeSlots += stat.getRight();
gotSlot = true; gotSlot = true;
break; break;
@@ -453,14 +484,14 @@ public class Equip extends Item {
int reqLevel = MapleItemInformationProvider.getInstance().getEquipStats(this.getItemId()).get("reqLevel"); int reqLevel = MapleItemInformationProvider.getInstance().getEquipStats(this.getItemId()).get("reqLevel");
float masteryModifier = (float)ExpTable.getExpNeededForLevel(1) / (float)normalizedMasteryExp(reqLevel); float masteryModifier = (float)ExpTable.getExpNeededForLevel(1) / (float)normalizedMasteryExp(reqLevel);
float elementModifier = (isElemental) ? 1.2f : 1.0f; float elementModifier = (isElemental) ? 0.85f : 0.6f;
float baseExpGain = gain * elementModifier * masteryModifier; float baseExpGain = gain * elementModifier * masteryModifier;
itemExp += baseExpGain; itemExp += baseExpGain;
int expNeeded = ExpTable.getEquipExpNeededForLevel(itemLevel); int expNeeded = ExpTable.getEquipExpNeededForLevel(itemLevel);
//System.out.println("Gain: " + gain + " Mastery: " + masteryModifier + "Base gain: " + baseExpGain + " item current exp: " + itemExp + " / " + expNeeded); //System.out.println("'" + MapleItemInformationProvider.getInstance().getName(this.getItemId()) + "' -> EXP Gain: " + gain + " Mastery: " + masteryModifier + "Base gain: " + baseExpGain + " exp: " + itemExp + " / " + expNeeded);
if (itemExp >= expNeeded) { if (itemExp >= expNeeded) {
while(itemExp >= expNeeded) { while(itemExp >= expNeeded) {

View File

@@ -40,6 +40,6 @@ public final class ExpTable {
} }
public static int getEquipExpNeededForLevel(int level) { public static int getEquipExpNeededForLevel(int level) {
return level > 30 ? 2000000000 : exp[level]; return equip[level];
} }
} }

View File

@@ -43,7 +43,7 @@ public class ServerConstants {
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically. public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
public static final boolean USE_ANOTHER_AUTOASSIGN = true; //Based on distributing AP accordingly with higher secondary stat on equipments. public static final boolean USE_ANOTHER_AUTOASSIGN = true; //Based on distributing AP accordingly with higher secondary stat on equipments.
public static final boolean USE_REFRESH_RANK_MOVE = true; public static final boolean USE_REFRESH_RANK_MOVE = true;
public static final int MAX_AP = 999; public static final int MAX_AP = 20000; //Max AP alloted on the auto-assigner.
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system. public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
public static final long BLOCK_DUEY_RACE_COND = (long)(0.5 * 1000); public static final long BLOCK_DUEY_RACE_COND = (long)(0.5 * 1000);
public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up. public static final long PET_LOOT_UPON_ATTACK = (long)(0.7 * 1000); //Time the pet must wait before trying to pick items up.
@@ -53,14 +53,15 @@ public class ServerConstants {
public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure. public static final boolean USE_PERFECT_SCROLLING = true; //Scrolls doesn't use slots upon failure.
public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade. public static final boolean USE_ENHANCED_CHSCROLL = true; //Equips even more powerful with chaos upgrade.
public static final boolean USE_ENHANCED_CRAFTING = true; //Applys chaos scroll on every equip crafted. public static final boolean USE_ENHANCED_CRAFTING = true; //Applys chaos scroll on every equip crafted.
public static final boolean USE_ULTRA_NIMBLE_FEET = true; //Still needs some client editing to work. public static final boolean USE_ULTRA_NIMBLE_FEET = true; //Haste-like speed & jump upgrade.
public static final boolean USE_ULTRA_RECOVERY = true; //Huehue another client edit. public static final boolean USE_ULTRA_RECOVERY = true; //Massive recovery amounts overtime.
//Public static final boolean USE_ULTRA_THREE_SNAILS = true; public static final boolean USE_ULTRA_THREE_SNAILS = true; //Massive damage on shell toss.
public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //Slots are added each 20 levels. public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //Slots are added each 20 levels.
public static final boolean USE_ADD_RATES_BY_LEVEL = true; //Rates are added each 20 levels. public static final boolean USE_ADD_RATES_BY_LEVEL = true; //Rates are added each 20 levels.
public static final boolean USE_STACK_COUPON_RATES = true; //Multiple coupons effects builds up together. public static final boolean USE_STACK_COUPON_RATES = true; //Multiple coupons effects builds up together.
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up. public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stats upgrades at equip level up. public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stats upgrades at equip level up.
public static final int MAX_EQUIPMNT_LVLUP_STAT_GAIN = 120; //Max stat upgrade an equipment can have on a levelup.
public static final int USE_EQUIPMNT_LVLUP = 7; //All equips lvlup at max level of N, set 0 to disable. public static final int USE_EQUIPMNT_LVLUP = 7; //All equips lvlup at max level of N, set 0 to disable.
public static final int FAME_GAIN_BY_QUEST = 4; //Fame gain each N quest completes, set 0 to disable. public static final int FAME_GAIN_BY_QUEST = 4; //Fame gain each N quest completes, set 0 to disable.
public static final int SCROLL_CHANCE_RATE = 10; //Number of tries for success on a scroll, set 0 for default. public static final int SCROLL_CHANCE_RATE = 10; //Number of tries for success on a scroll, set 0 for default.

View File

@@ -62,6 +62,7 @@ import client.status.MonsterStatus;
import client.status.MonsterStatusEffect; import client.status.MonsterStatusEffect;
import constants.GameConstants; import constants.GameConstants;
import constants.ItemConstants; import constants.ItemConstants;
import constants.ServerConstants;
import constants.skills.Aran; import constants.skills.Aran;
import constants.skills.Assassin; import constants.skills.Assassin;
import constants.skills.Bandit; import constants.skills.Bandit;
@@ -104,6 +105,7 @@ import constants.skills.SuperGM;
import constants.skills.ThunderBreaker; import constants.skills.ThunderBreaker;
import constants.skills.WhiteKnight; import constants.skills.WhiteKnight;
import constants.skills.WindArcher; import constants.skills.WindArcher;
import scripting.AbstractPlayerInteraction;
public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandler { public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandler {
@@ -191,9 +193,9 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
} }
//WTF IS THIS F3,1 //WTF IS THIS F3,1
/*if (attackCount != attack.numDamage && attack.skill != ChiefBandit.MESO_EXPLOSION && attack.skill != NightWalker.VAMPIRE && attack.skill != WindArcher.WIND_SHOT && attack.skill != Aran.COMBO_SMASH && attack.skill != Aran.COMBO_PENRIL && attack.skill != Aran.COMBO_TEMPEST && attack.skill != NightLord.NINJA_AMBUSH && attack.skill != Shadower.NINJA_AMBUSH) { /*if (attackCount != attack.numDamage && attack.skill != ChiefBandit.MESO_EXPLOSION && attack.skill != NightWalker.VAMPIRE && attack.skill != WindArcher.WIND_SHOT && attack.skill != Aran.COMBO_SMASH && attack.skill != Aran.COMBO_PENRIL && attack.skill != Aran.COMBO_TEMPEST && attack.skill != NightLord.NINJA_AMBUSH && attack.skill != Shadower.NINJA_AMBUSH) {
return; return;
}*/ }*/
int totDamage = 0; int totDamage = 0;
final MapleMap map = player.getMap(); final MapleMap map = player.getMap();
@@ -204,9 +206,9 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
MapleMapObject mapobject = map.getMapObject(oned.intValue()); MapleMapObject mapobject = map.getMapObject(oned.intValue());
if (mapobject != null && mapobject.getType() == MapleMapObjectType.ITEM) { if (mapobject != null && mapobject.getType() == MapleMapObjectType.ITEM) {
final MapleMapItem mapitem = (MapleMapItem) mapobject; final MapleMapItem mapitem = (MapleMapItem) mapobject;
if (mapitem.getMeso() == 0) { //Maybe it is possible some how? if (mapitem.getMeso() == 0) { //Maybe it is possible some how?
return; return;
} }
synchronized (mapitem) { synchronized (mapitem) {
if (mapitem.isPickedUp()) { if (mapitem.isPickedUp()) {
return; return;
@@ -263,8 +265,7 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
int totDamageToOneMonster = 0; int totDamageToOneMonster = 0;
List<Integer> onedList = attack.allDamage.get(oned); List<Integer> onedList = attack.allDamage.get(oned);
for (Integer eachd : onedList) { for (Integer eachd : onedList) {
if(eachd < 0) if(eachd < 0) eachd += Integer.MAX_VALUE;
eachd += Integer.MAX_VALUE;
totDamageToOneMonster += eachd; totDamageToOneMonster += eachd;
} }
totDamage += totDamageToOneMonster; totDamage += totDamageToOneMonster;
@@ -296,20 +297,20 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
} else if (attack.skill == Bandit.STEAL) { } else if (attack.skill == Bandit.STEAL) {
Skill steal = SkillFactory.getSkill(Bandit.STEAL); Skill steal = SkillFactory.getSkill(Bandit.STEAL);
if (monster.getStolen().size() < 1) { // One steal per mob <3 if (monster.getStolen().size() < 1) { // One steal per mob <3
if (Math.random() < 0.3 && steal.getEffect(player.getSkillLevel(steal)).makeChanceResult()) { //Else it drops too many cool stuff :( if (Math.random() < 0.3 && steal.getEffect(player.getSkillLevel(steal)).makeChanceResult()) { //Else it drops too many cool stuff :(
List<MonsterDropEntry> toSteals = MapleMonsterInformationProvider.getInstance().retrieveDrop(monster.getId()); List<MonsterDropEntry> toSteals = MapleMonsterInformationProvider.getInstance().retrieveDrop(monster.getId());
Collections.shuffle(toSteals); Collections.shuffle(toSteals);
int toSteal = toSteals.get(rand(0, (toSteals.size() - 1))).itemId; int toSteal = toSteals.get(rand(0, (toSteals.size() - 1))).itemId;
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
Item item; Item item;
if (ItemConstants.getInventoryType(toSteal).equals(MapleInventoryType.EQUIP)) { if (ItemConstants.getInventoryType(toSteal).equals(MapleInventoryType.EQUIP)) {
item = ii.randomizeStats((Equip) ii.getEquipById(toSteal)); item = ii.randomizeStats((Equip) ii.getEquipById(toSteal));
} else { } else {
item = new Item(toSteal, (byte) 0, (short) 1, -1); item = new Item(toSteal, (byte) 0, (short) 1, -1);
} }
player.getMap().spawnItemDrop(monster, player, item, monster.getPosition(), false, false); player.getMap().spawnItemDrop(monster, player, item, monster.getPosition(), false, false);
monster.addStolen(toSteal); monster.addStolen(toSteal);
} }
} }
} else if (attack.skill == FPArchMage.FIRE_DEMON) { } else if (attack.skill == FPArchMage.FIRE_DEMON) {
monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, SkillFactory.getSkill(FPArchMage.FIRE_DEMON).getEffect(player.getSkillLevel(SkillFactory.getSkill(FPArchMage.FIRE_DEMON))).getDuration() * 1000); monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, SkillFactory.getSkill(FPArchMage.FIRE_DEMON).getEffect(player.getSkillLevel(SkillFactory.getSkill(FPArchMage.FIRE_DEMON))).getDuration() * 1000);
@@ -322,11 +323,11 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
if (job == 2111 || job == 2112) { if (job == 2111 || job == 2112) {
if (player.getBuffedValue(MapleBuffStat.WK_CHARGE) != null) { if (player.getBuffedValue(MapleBuffStat.WK_CHARGE) != null) {
Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE); Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE);
if (totDamageToOneMonster > 0) { if (totDamageToOneMonster > 0) {
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false); MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false);
monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000); monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000);
} }
} }
} }
if (player.getBuffedValue(MapleBuffStat.HAMSTRING) != null) { if (player.getBuffedValue(MapleBuffStat.HAMSTRING) != null) {
@@ -355,26 +356,26 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
Skill chargeSkill = SkillFactory.getSkill(charge); Skill chargeSkill = SkillFactory.getSkill(charge);
if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) { if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
if (totDamageToOneMonster > 0) { if (totDamageToOneMonster > 0) {
if (charge == WhiteKnight.BW_ICE_CHARGE || charge == WhiteKnight.SWORD_ICE_CHARGE) { if (charge == WhiteKnight.BW_ICE_CHARGE || charge == WhiteKnight.SWORD_ICE_CHARGE) {
monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000); monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break; break;
} }
if (charge == WhiteKnight.BW_FIRE_CHARGE || charge == WhiteKnight.SWORD_FIRE_CHARGE) { if (charge == WhiteKnight.BW_FIRE_CHARGE || charge == WhiteKnight.SWORD_FIRE_CHARGE) {
monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000); monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break; break;
} }
} }
} }
} }
if (job == 122) { if (job == 122) {
for (int charge = 1221003; charge < 1221004; charge++) { for (int charge = 1221003; charge < 1221004; charge++) {
Skill chargeSkill = SkillFactory.getSkill(charge); Skill chargeSkill = SkillFactory.getSkill(charge);
if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) { if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
if (totDamageToOneMonster > 0) { if (totDamageToOneMonster > 0) {
monster.setTempEffectiveness(Element.HOLY, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000); monster.setTempEffectiveness(Element.HOLY, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break; break;
} }
} }
} }
} }
} else if (player.getBuffedValue(MapleBuffStat.COMBO_DRAIN) != null) { } else if (player.getBuffedValue(MapleBuffStat.COMBO_DRAIN) != null) {
@@ -400,29 +401,29 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
} }
} else if (job == 521 || job == 522) { // from what I can gather this is how it should work } else if (job == 521 || job == 522) { // from what I can gather this is how it should work
if (!monster.isBoss()) { if (!monster.isBoss()) {
Skill type = SkillFactory.getSkill(Outlaw.FLAME_THROWER); Skill type = SkillFactory.getSkill(Outlaw.FLAME_THROWER);
if (player.getSkillLevel(type) > 0) { if (player.getSkillLevel(type) > 0) {
MapleStatEffect DoT = type.getEffect(player.getSkillLevel(type)); MapleStatEffect DoT = type.getEffect(player.getSkillLevel(type));
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false); MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false);
monster.applyStatus(player, monsterStatusEffect, true, DoT.getDuration(), false); monster.applyStatus(player, monsterStatusEffect, true, DoT.getDuration(), false);
} }
} }
} else if (job >= 311 && job <= 322) { } else if (job >= 311 && job <= 322) {
if (!monster.isBoss()) { if (!monster.isBoss()) {
Skill mortalBlow; Skill mortalBlow;
if (job == 311 || job == 312) { if (job == 311 || job == 312) {
mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW); mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW);
} else { } else {
mortalBlow = SkillFactory.getSkill(Sniper.MORTAL_BLOW); mortalBlow = SkillFactory.getSkill(Sniper.MORTAL_BLOW);
} }
if (player.getSkillLevel(mortalBlow) > 0) { if (player.getSkillLevel(mortalBlow) > 0) {
MapleStatEffect mortal = mortalBlow.getEffect(player.getSkillLevel(mortalBlow)); MapleStatEffect mortal = mortalBlow.getEffect(player.getSkillLevel(mortalBlow));
if (monster.getHp() <= (monster.getStats().getHp() * mortal.getX()) / 100) { if (monster.getHp() <= (monster.getStats().getHp() * mortal.getX()) / 100) {
if (Randomizer.rand(1, 100) <= mortal.getY()) { if (Randomizer.rand(1, 100) <= mortal.getY()) {
monster.getMap().killMonster(monster, player, true); monster.getMap().killMonster(monster, player, true);
} }
} }
} }
} }
} }
if (attack.skill != 0) { if (attack.skill != 0) {
@@ -430,6 +431,32 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
if (totDamageToOneMonster != attackEffect.getFixDamage() && totDamageToOneMonster != 0) { if (totDamageToOneMonster != attackEffect.getFixDamage() && totDamageToOneMonster != 0) {
AutobanFactory.FIX_DAMAGE.autoban(player, String.valueOf(totDamageToOneMonster) + " damage"); AutobanFactory.FIX_DAMAGE.autoban(player, String.valueOf(totDamageToOneMonster) + " damage");
} }
if(ServerConstants.USE_ULTRA_THREE_SNAILS) {
AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
int shellId;
switch(totDamageToOneMonster) {
case 10:
shellId = 4000019;
break;
case 25:
shellId = 4000000;
break;
default:
shellId = 4000016;
}
if(api.haveItem(shellId, 1)) {
api.gainItem(shellId, (short)-1, false);
totDamageToOneMonster *= player.getLevel();
}
else {
player.dropMessage(5, "You ran out of shells to use to activate the hidden power of Three Snails.");
}
}
} }
} }
if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.getMonsterStati().size() > 0) { if (totDamageToOneMonster > 0 && attackEffect != null && attackEffect.getMonsterStati().size() > 0) {

View File

@@ -54,11 +54,11 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
MapleCharacter player = c.getPlayer(); MapleCharacter player = c.getPlayer();
player.setPetLootCd(System.currentTimeMillis()); player.setPetLootCd(System.currentTimeMillis());
/*long timeElapsed = System.currentTimeMillis() - player.getAutobanManager().getLastSpam(8); /*long timeElapsed = System.currentTimeMillis() - player.getAutobanManager().getLastSpam(8);
if(timeElapsed < 300) { if(timeElapsed < 300) {
AutobanFactory.FAST_ATTACK.alert(player, "Time: " + timeElapsed); AutobanFactory.FAST_ATTACK.alert(player, "Time: " + timeElapsed);
} }
player.getAutobanManager().spam(8);*/ player.getAutobanManager().spam(8);*/
AttackInfo attack = parseDamage(slea, player, true, false); AttackInfo attack = parseDamage(slea, player, true, false);
@@ -141,19 +141,19 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
} }
boolean soulArrow = player.getBuffedValue(MapleBuffStat.SOULARROW) != null; boolean soulArrow = player.getBuffedValue(MapleBuffStat.SOULARROW) != null;
boolean shadowClaw = player.getBuffedValue(MapleBuffStat.SHADOW_CLAW) != null; boolean shadowClaw = player.getBuffedValue(MapleBuffStat.SHADOW_CLAW) != null;
if (projectile != 0) { if (projectile != 0) {
if (!soulArrow && !shadowClaw && attack.skill != 11101004 && attack.skill != 15111007 && attack.skill != 14101006) { if (!soulArrow && !shadowClaw && attack.skill != 11101004 && attack.skill != 15111007 && attack.skill != 14101006) {
byte bulletConsume = bulletCount; byte bulletConsume = bulletCount;
if (effect != null && effect.getBulletConsume() != 0) { if (effect != null && effect.getBulletConsume() != 0) {
bulletConsume = (byte) (effect.getBulletConsume() * (hasShadowPartner ? 2 : 1)); bulletConsume = (byte) (effect.getBulletConsume() * (hasShadowPartner ? 2 : 1));
} }
if(slot < 0) System.out.println("<ERROR> Projectile to use was unable to be found."); if(slot < 0) System.out.println("<ERROR> Projectile to use was unable to be found.");
else MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, bulletConsume, false, true); else MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, bulletConsume, false, true);
} }
} }
if (projectile != 0 || soulArrow || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) { if (projectile != 0 || soulArrow || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) {
int visProjectile = projectile; //visible projectile sent to players int visProjectile = projectile; //visible projectile sent to players
if (ItemConstants.isThrowingStar(projectile)) { if (ItemConstants.isThrowingStar(projectile)) {
MapleInventory cash = player.getInventory(MapleInventoryType.CASH); MapleInventory cash = player.getInventory(MapleInventoryType.CASH);

View File

@@ -648,7 +648,7 @@ public class EventInstanceManager {
} }
private void dropExclusiveItems(MapleCharacter chr) { private void dropExclusiveItems(MapleCharacter chr) {
AbstractPlayerInteraction api = new AbstractPlayerInteraction(chr.getClient()); AbstractPlayerInteraction api = chr.getClient().getAbstractPlayerInteraction();
for(Integer item: exclusiveItems) { for(Integer item: exclusiveItems) {
api.removeAll(item); api.removeAll(item);
@@ -749,7 +749,7 @@ public class EventInstanceManager {
if(!hasRewardSlot(player, eventLevel)) return false; if(!hasRewardSlot(player, eventLevel)) return false;
AbstractPlayerInteraction api = new AbstractPlayerInteraction(player.getClient()); AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
int rnd = (int)Math.floor(Math.random() * rewardsSet.size()); int rnd = (int)Math.floor(Math.random() * rewardsSet.size());
api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue()); api.gainItem(rewardsSet.get(rnd), rewardsQty.get(rnd).shortValue());

View File

@@ -371,8 +371,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
} }
attacker.gainExp(personalExp, partyExp, true, false, isKiller); attacker.gainExp(personalExp, partyExp, true, false, isKiller);
attacker.mobKilled(getId());
attacker.increaseEquipExp(personalExp); attacker.increaseEquipExp(personalExp);
attacker.mobKilled(getId());
} }
} }