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=

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.
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>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<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/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/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/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/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/tools/MaplePacketCreator.java</file>
</group>

View File

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

View File

@@ -48,6 +48,24 @@ public class Equip extends Item {
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 level, flag, itemLevel;
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) {
Map<Integer, Integer> pool = new HashMap<>();
pool.put(0, 1);
pool.put(1, 1);
for(int i = 2; i <= limit; i++) {
for(int j = 0; j < i; j++) {
pool.put(j, pool.get(j) + 1);
}
pool.put(i, 1);
int top = Math.min(limit, ServerConstants.MAX_EQUIPMNT_LVLUP_STAT_GAIN);
pool.put(0, top);
for(int i = 1; i <= top; i++) {
pool.put(i, top - i + 1);
}
int poolCount = 0;
@@ -303,7 +318,7 @@ public class Equip extends Item {
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;
int maxUpgrade = randomizeStatUpgrade((int)(1 + (curStat / getStatModifier(isAttribute))));
@@ -312,118 +327,134 @@ public class Equip extends Item {
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) {
stats.add(new Pair<>(name, 1)); // 10% success on getting a slot upgrade.
}
}
private void improveDefaultStats(List<Pair<String, Integer>> stats) {
if(dex > 0) getUnitStatUpgrade(stats, "incDEX", dex, true);
if(str > 0) getUnitStatUpgrade(stats, "incSTR", str, true);
if(_int > 0) getUnitStatUpgrade(stats, "incINT",_int, true);
if(luk > 0) getUnitStatUpgrade(stats, "incLUK", luk, true);
if(hp > 0) getUnitStatUpgrade(stats, "incMHP", hp, false);
if(mp > 0) getUnitStatUpgrade(stats, "incMMP", mp, false);
if(watk > 0) getUnitStatUpgrade(stats, "incPAD", watk, false);
if(matk > 0) getUnitStatUpgrade(stats, "incMAD", matk, false);
if(wdef > 0) getUnitStatUpgrade(stats, "incPDD", wdef, false);
if(mdef > 0) getUnitStatUpgrade(stats, "incMDD", mdef, false);
if(avoid > 0) getUnitStatUpgrade(stats, "incEVA", avoid, false);
if(acc > 0) getUnitStatUpgrade(stats, "incACC", acc, false);
if(speed > 0) getUnitStatUpgrade(stats, "incSpeed", speed, false);
if(jump > 0) getUnitStatUpgrade(stats, "incJump", jump, false);
private void improveDefaultStats(List<Pair<StatUpgrade, Integer>> stats) {
if(dex > 0) getUnitStatUpgrade(stats, StatUpgrade.incDEX, dex, true);
if(str > 0) getUnitStatUpgrade(stats, StatUpgrade.incSTR, str, true);
if(_int > 0) getUnitStatUpgrade(stats, StatUpgrade.incINT,_int, true);
if(luk > 0) getUnitStatUpgrade(stats, StatUpgrade.incLUK, luk, true);
if(hp > 0) getUnitStatUpgrade(stats, StatUpgrade.incMHP, hp, false);
if(mp > 0) getUnitStatUpgrade(stats, StatUpgrade.incMMP, mp, false);
if(watk > 0) getUnitStatUpgrade(stats, StatUpgrade.incPAD, watk, false);
if(matk > 0) getUnitStatUpgrade(stats, StatUpgrade.incMAD, matk, false);
if(wdef > 0) getUnitStatUpgrade(stats, StatUpgrade.incPDD, wdef, false);
if(mdef > 0) getUnitStatUpgrade(stats, StatUpgrade.incMDD, mdef, false);
if(avoid > 0) getUnitStatUpgrade(stats, StatUpgrade.incEVA, avoid, false);
if(acc > 0) getUnitStatUpgrade(stats, StatUpgrade.incACC, acc, false);
if(speed > 0) getUnitStatUpgrade(stats, StatUpgrade.incSpeed, speed, false);
if(jump > 0) getUnitStatUpgrade(stats, StatUpgrade.incJump, jump, false);
}
public void gainLevel(MapleClient c) {
List<Pair<String, Integer>> stats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel);
private void gainLevel(MapleClient c) {
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(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, "incVicious");
getUnitSlotUpgrade(stats, "incSlot");
if(vicious > 0) getUnitSlotUpgrade(stats, StatUpgrade.incVicious);
getUnitSlotUpgrade(stats, StatUpgrade.incSlot);
}
}
else {
isUpgradeable = false;
do {
improveDefaultStats(stats);
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, "incVicious");
getUnitSlotUpgrade(stats, "incSlot");
improveDefaultStats(stats);
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
if(vicious > 0) getUnitSlotUpgrade(stats, StatUpgrade.incVicious);
getUnitSlotUpgrade(stats, StatUpgrade.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++;
boolean gotVicious = false, gotSlot = false;
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()) {
case "incDEX":
case incDEX:
dex += stat.getRight();
lvupStr += "+" + stat.getRight() + "DEX ";
break;
case "incSTR":
case incSTR:
str += stat.getRight();
lvupStr += "+" + stat.getRight() + "STR ";
break;
case "incINT":
case incINT:
_int += stat.getRight();
lvupStr += "+" + stat.getRight() + "INT ";
break;
case "incLUK":
case incLUK:
luk += stat.getRight();
lvupStr += "+" + stat.getRight() + "LUK ";
break;
case "incMHP":
case incMHP:
hp += stat.getRight();
lvupStr += "+" + stat.getRight() + "HP ";
break;
case "incMMP":
case incMMP:
mp += stat.getRight();
lvupStr += "+" + stat.getRight() + "MP ";
break;
case "incPAD":
case incPAD:
watk += stat.getRight();
lvupStr += "+" + stat.getRight() + "WATK ";
break;
case "incMAD":
case incMAD:
matk += stat.getRight();
lvupStr += "+" + stat.getRight() + "MATK ";
break;
case "incPDD":
case incPDD:
wdef += stat.getRight();
lvupStr += "+" + stat.getRight() + "WDEF ";
break;
case "incMDD":
case incMDD:
mdef += stat.getRight();
lvupStr += "+" + stat.getRight() + "MDEF ";
break;
case "incEVA":
case incEVA:
avoid += stat.getRight();
lvupStr += "+" + stat.getRight() + "AVOID ";
break;
case "incACC":
case incACC:
acc += stat.getRight();
lvupStr += "+" + stat.getRight() + "ACC ";
break;
case "incSpeed":
case incSpeed:
speed += stat.getRight();
lvupStr += "+" + stat.getRight() + "SPEED ";
break;
case "incJump":
case incJump:
jump += stat.getRight();
lvupStr += "+" + stat.getRight() + "JUMP ";
break;
case "incVicious":
case incVicious:
vicious -= stat.getRight();
gotVicious = true;
break;
case "incSlot":
case incSlot:
upgradeSlots += stat.getRight();
gotSlot = true;
break;
@@ -453,14 +484,14 @@ public class Equip extends Item {
int reqLevel = MapleItemInformationProvider.getInstance().getEquipStats(this.getItemId()).get("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;
itemExp += baseExpGain;
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) {
while(itemExp >= expNeeded) {

View File

@@ -40,6 +40,6 @@ public final class ExpTable {
}
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_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 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 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.
@@ -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_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_ULTRA_NIMBLE_FEET = true; //Still needs some client editing to work.
public static final boolean USE_ULTRA_RECOVERY = true; //Huehue another client edit.
//Public static final boolean USE_ULTRA_THREE_SNAILS = true;
public static final boolean USE_ULTRA_NIMBLE_FEET = true; //Haste-like speed & jump upgrade.
public static final boolean USE_ULTRA_RECOVERY = true; //Massive recovery amounts overtime.
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_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_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 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 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.

View File

@@ -62,6 +62,7 @@ import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import constants.GameConstants;
import constants.ItemConstants;
import constants.ServerConstants;
import constants.skills.Aran;
import constants.skills.Assassin;
import constants.skills.Bandit;
@@ -104,6 +105,7 @@ import constants.skills.SuperGM;
import constants.skills.ThunderBreaker;
import constants.skills.WhiteKnight;
import constants.skills.WindArcher;
import scripting.AbstractPlayerInteraction;
public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandler {
@@ -191,9 +193,9 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
}
//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) {
return;
}*/
/*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;
}*/
int totDamage = 0;
final MapleMap map = player.getMap();
@@ -204,9 +206,9 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
MapleMapObject mapobject = map.getMapObject(oned.intValue());
if (mapobject != null && mapobject.getType() == MapleMapObjectType.ITEM) {
final MapleMapItem mapitem = (MapleMapItem) mapobject;
if (mapitem.getMeso() == 0) { //Maybe it is possible some how?
return;
}
if (mapitem.getMeso() == 0) { //Maybe it is possible some how?
return;
}
synchronized (mapitem) {
if (mapitem.isPickedUp()) {
return;
@@ -263,8 +265,7 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
int totDamageToOneMonster = 0;
List<Integer> onedList = attack.allDamage.get(oned);
for (Integer eachd : onedList) {
if(eachd < 0)
eachd += Integer.MAX_VALUE;
if(eachd < 0) eachd += Integer.MAX_VALUE;
totDamageToOneMonster += eachd;
}
totDamage += totDamageToOneMonster;
@@ -296,20 +297,20 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
} else if (attack.skill == Bandit.STEAL) {
Skill steal = SkillFactory.getSkill(Bandit.STEAL);
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 :(
List<MonsterDropEntry> toSteals = MapleMonsterInformationProvider.getInstance().retrieveDrop(monster.getId());
Collections.shuffle(toSteals);
int toSteal = toSteals.get(rand(0, (toSteals.size() - 1))).itemId;
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
Item item;
if (ItemConstants.getInventoryType(toSteal).equals(MapleInventoryType.EQUIP)) {
item = ii.randomizeStats((Equip) ii.getEquipById(toSteal));
} else {
item = new Item(toSteal, (byte) 0, (short) 1, -1);
}
player.getMap().spawnItemDrop(monster, player, item, monster.getPosition(), false, false);
monster.addStolen(toSteal);
}
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());
Collections.shuffle(toSteals);
int toSteal = toSteals.get(rand(0, (toSteals.size() - 1))).itemId;
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
Item item;
if (ItemConstants.getInventoryType(toSteal).equals(MapleInventoryType.EQUIP)) {
item = ii.randomizeStats((Equip) ii.getEquipById(toSteal));
} else {
item = new Item(toSteal, (byte) 0, (short) 1, -1);
}
player.getMap().spawnItemDrop(monster, player, item, monster.getPosition(), false, false);
monster.addStolen(toSteal);
}
}
} 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);
@@ -322,11 +323,11 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
if (job == 2111 || job == 2112) {
if (player.getBuffedValue(MapleBuffStat.WK_CHARGE) != null) {
Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE);
if (totDamageToOneMonster > 0) {
Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE);
if (totDamageToOneMonster > 0) {
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false);
monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000);
}
}
}
}
if (player.getBuffedValue(MapleBuffStat.HAMSTRING) != null) {
@@ -355,26 +356,26 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
Skill chargeSkill = SkillFactory.getSkill(charge);
if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
if (totDamageToOneMonster > 0) {
if (charge == WhiteKnight.BW_ICE_CHARGE || charge == WhiteKnight.SWORD_ICE_CHARGE) {
monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
if (charge == WhiteKnight.BW_FIRE_CHARGE || charge == WhiteKnight.SWORD_FIRE_CHARGE) {
monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
if (charge == WhiteKnight.BW_ICE_CHARGE || charge == WhiteKnight.SWORD_ICE_CHARGE) {
monster.setTempEffectiveness(Element.ICE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
if (charge == WhiteKnight.BW_FIRE_CHARGE || charge == WhiteKnight.SWORD_FIRE_CHARGE) {
monster.setTempEffectiveness(Element.FIRE, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
}
}
}
if (job == 122) {
for (int charge = 1221003; charge < 1221004; charge++) {
Skill chargeSkill = SkillFactory.getSkill(charge);
if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
if (totDamageToOneMonster > 0) {
monster.setTempEffectiveness(Element.HOLY, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
}
for (int charge = 1221003; charge < 1221004; charge++) {
Skill chargeSkill = SkillFactory.getSkill(charge);
if (player.isBuffFrom(MapleBuffStat.WK_CHARGE, chargeSkill)) {
if (totDamageToOneMonster > 0) {
monster.setTempEffectiveness(Element.HOLY, ElementalEffectiveness.WEAK, chargeSkill.getEffect(player.getSkillLevel(chargeSkill)).getY() * 1000);
break;
}
}
}
}
} else if (player.getBuffedValue(MapleBuffStat.COMBO_DRAIN) != null) {
@@ -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
if (!monster.isBoss()) {
Skill type = SkillFactory.getSkill(Outlaw.FLAME_THROWER);
if (player.getSkillLevel(type) > 0) {
MapleStatEffect DoT = type.getEffect(player.getSkillLevel(type));
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false);
monster.applyStatus(player, monsterStatusEffect, true, DoT.getDuration(), false);
}
}
Skill type = SkillFactory.getSkill(Outlaw.FLAME_THROWER);
if (player.getSkillLevel(type) > 0) {
MapleStatEffect DoT = type.getEffect(player.getSkillLevel(type));
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.POISON, 1), type, null, false);
monster.applyStatus(player, monsterStatusEffect, true, DoT.getDuration(), false);
}
}
} else if (job >= 311 && job <= 322) {
if (!monster.isBoss()) {
Skill mortalBlow;
if (job == 311 || job == 312) {
mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW);
} else {
mortalBlow = SkillFactory.getSkill(Sniper.MORTAL_BLOW);
}
if (player.getSkillLevel(mortalBlow) > 0) {
MapleStatEffect mortal = mortalBlow.getEffect(player.getSkillLevel(mortalBlow));
if (monster.getHp() <= (monster.getStats().getHp() * mortal.getX()) / 100) {
if (Randomizer.rand(1, 100) <= mortal.getY()) {
monster.getMap().killMonster(monster, player, true);
}
}
}
Skill mortalBlow;
if (job == 311 || job == 312) {
mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW);
} else {
mortalBlow = SkillFactory.getSkill(Sniper.MORTAL_BLOW);
}
if (player.getSkillLevel(mortalBlow) > 0) {
MapleStatEffect mortal = mortalBlow.getEffect(player.getSkillLevel(mortalBlow));
if (monster.getHp() <= (monster.getStats().getHp() * mortal.getX()) / 100) {
if (Randomizer.rand(1, 100) <= mortal.getY()) {
monster.getMap().killMonster(monster, player, true);
}
}
}
}
}
if (attack.skill != 0) {
@@ -430,6 +431,32 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
if (totDamageToOneMonster != attackEffect.getFixDamage() && totDamageToOneMonster != 0) {
AutobanFactory.FIX_DAMAGE.autoban(player, String.valueOf(totDamageToOneMonster) + " damage");
}
if(ServerConstants.USE_ULTRA_THREE_SNAILS) {
AbstractPlayerInteraction api = player.getClient().getAbstractPlayerInteraction();
int shellId;
switch(totDamageToOneMonster) {
case 10:
shellId = 4000019;
break;
case 25:
shellId = 4000000;
break;
default:
shellId = 4000016;
}
if(api.haveItem(shellId, 1)) {
api.gainItem(shellId, (short)-1, false);
totDamageToOneMonster *= player.getLevel();
}
else {
player.dropMessage(5, "You ran out of shells to use to activate the hidden power of Three Snails.");
}
}
}
}
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();
player.setPetLootCd(System.currentTimeMillis());
/*long timeElapsed = System.currentTimeMillis() - player.getAutobanManager().getLastSpam(8);
if(timeElapsed < 300) {
AutobanFactory.FAST_ATTACK.alert(player, "Time: " + timeElapsed);
}
player.getAutobanManager().spam(8);*/
/*long timeElapsed = System.currentTimeMillis() - player.getAutobanManager().getLastSpam(8);
if(timeElapsed < 300) {
AutobanFactory.FAST_ATTACK.alert(player, "Time: " + timeElapsed);
}
player.getAutobanManager().spam(8);*/
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 shadowClaw = player.getBuffedValue(MapleBuffStat.SHADOW_CLAW) != null;
if (projectile != 0) {
if (!soulArrow && !shadowClaw && attack.skill != 11101004 && attack.skill != 15111007 && attack.skill != 14101006) {
byte bulletConsume = bulletCount;
if (effect != null && effect.getBulletConsume() != 0) {
bulletConsume = (byte) (effect.getBulletConsume() * (hasShadowPartner ? 2 : 1));
}
if(slot < 0) System.out.println("<ERROR> Projectile to use was unable to be found.");
else MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, bulletConsume, false, true);
}
if (projectile != 0) {
if (!soulArrow && !shadowClaw && attack.skill != 11101004 && attack.skill != 15111007 && attack.skill != 14101006) {
byte bulletConsume = bulletCount;
if (effect != null && effect.getBulletConsume() != 0) {
bulletConsume = (byte) (effect.getBulletConsume() * (hasShadowPartner ? 2 : 1));
}
if(slot < 0) System.out.println("<ERROR> Projectile to use was unable to be found.");
else MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, bulletConsume, false, true);
}
}
if (projectile != 0 || soulArrow || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) {
if (projectile != 0 || soulArrow || attack.skill == 11101004 || attack.skill == 15111007 || attack.skill == 14101006) {
int visProjectile = projectile; //visible projectile sent to players
if (ItemConstants.isThrowingStar(projectile)) {
MapleInventory cash = player.getInventory(MapleInventoryType.CASH);

View File

@@ -648,7 +648,7 @@ public class EventInstanceManager {
}
private void dropExclusiveItems(MapleCharacter chr) {
AbstractPlayerInteraction api = new AbstractPlayerInteraction(chr.getClient());
AbstractPlayerInteraction api = chr.getClient().getAbstractPlayerInteraction();
for(Integer item: exclusiveItems) {
api.removeAll(item);
@@ -749,7 +749,7 @@ public class EventInstanceManager {
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());
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.mobKilled(getId());
attacker.increaseEquipExp(personalExp);
attacker.mobKilled(getId());
}
}