Equipment Level-up

Added mechanics to permit equipment level-up for every equipment in the
game. Added a new EXP table for equipments.
This commit is contained in:
ronancpl
2017-06-01 00:50:07 -03:00
parent f30acb3b8a
commit a6ac40a351
49 changed files with 167 additions and 55 deletions

View File

@@ -8,7 +8,7 @@ Regarding distributability and usage of the code presented here: like it was bef
This is a NetBeans 8.0.2 Project. This means that it's easier to install the project via opening the server project folder inside NetBeans' IDE. Once installed, build this project on your machine and run the server using the "launch.bat" application.
In this project, many gameplay-wise issues generated from either the original WZ files and the server sources have been partially or completely solved. From now on, considering the use of some of this system's edited WZ and server-side files should be a great asset for new private server instances. My opinion, though! Refer to "README_wzchanges.txt" for more information on what have been changed from Nexon's v83 WZ files.
In this project, many gameplay-wise issues generated from either the original WZ files and the server sources have been partially or completely solved. Considering the use of the provided edited WZ's and server-side wz.xml files should be of the greatest importance when dealing with this instance of private server, in order to perceive it at it's full potential. My opinion, though! Refer to "README_wzchanges.txt" for more information on what have been changed from Nexon's v83 WZ files.
The main objective of this project is to try as best as possible to recreate what once was the original MapleStory v83, while adding up some flavors that spices up the gameplay. In other words, to aim to get the best of the MapleStory of that era.

View File

@@ -1,4 +1,4 @@
#Tue, 30 May 2017 23:04:14 -0300
#Thu, 01 Jun 2017 00:42:50 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=

BIN
dist/MapleSolaxia.jar vendored

Binary file not shown.

View File

@@ -267,4 +267,8 @@ Adi
29 - 30 Maio 2017,
Implementação da estrutura referente aos cupons de UP EXP & drop.
MapleCouponInstaller: ferramenta desenvolvida para coleta de informações referentes ao rate e faixa de tempo que os cupons se ativam.
MapleCouponInstaller: ferramenta desenvolvida para coleta de informações referentes ao rate e faixa de tempo que os cupons se ativam.
31 Maio 2017,
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.

View File

@@ -12,6 +12,8 @@
</editor-bookmarks>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/Server.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/CouponWorker.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java</file>
</group>
</open-files>

View File

@@ -150,10 +150,6 @@ import scripting.item.ItemScriptManager;
import server.maps.MapleMapItem;
public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private static final int[] DROP_RATE_GAIN = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
private static final int[] MESO_RATE_GAIN = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66};
private static final int[] EXP_RATE_GAIN = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}; //fibonacci :3
private static final String LEVEL_200 = "[Congrats] %s has reached Level 200! Congratulate %s on such an amazing achievement!";
// MapleStory default keyset
@@ -3383,15 +3379,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
public void setPlayerRates() {
this.expRate *= EXP_RATE_GAIN[this.level / 20];
this.mesoRate *= MESO_RATE_GAIN[this.level / 20];
this.dropRate *= DROP_RATE_GAIN[this.level / 20];
this.expRate *= GameConstants.getPlayerBonusExpRate(this.level / 20);
this.mesoRate *= GameConstants.getPlayerBonusMesoRate(this.level / 20);
this.dropRate *= GameConstants.getPlayerBonusDropRate(this.level / 20);
}
public void revertPlayerRates() {
this.expRate /= EXP_RATE_GAIN[(this.level - 1) / 20];
this.mesoRate /= MESO_RATE_GAIN[(this.level - 1) / 20];
this.dropRate /= DROP_RATE_GAIN[(this.level - 1) / 20];
this.expRate /= GameConstants.getPlayerBonusExpRate((this.level - 1) / 20);
this.mesoRate /= GameConstants.getPlayerBonusMesoRate((this.level - 1) / 20);
this.dropRate /= GameConstants.getPlayerBonusDropRate((this.level - 1) / 20);
}
public void revertWorldRates() {
@@ -3945,7 +3941,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
}
} catch (Exception e) {
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, e, "MapleCharacter.mobKilled. CID: " + this.id + " last Quest Processed: " + lastQuestProcessed);
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, e, "MapleCharacter.mobKilled. CID: " + this.id + " last Quest Processed: " + lastQuestProcessed);
}
}
@@ -5964,7 +5960,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
pendantExp = 0;
}
public void increaseEquipExp(int mobexp) {
public void increaseEquipExp(int expGain) {
if(expGain < 0) expGain = Integer.MAX_VALUE;
MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
for (Item item : getInventory(MapleInventoryType.EQUIPPED).list()) {
Equip nEquip = (Equip) item;
@@ -5973,8 +5971,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
continue;
}
if ((nEquip.getItemLevel() < ServerConstants.USE_EQUIPMNT_LVLUP) && (itemName.contains("Reverse") && nEquip.getItemLevel() < 4) || itemName.contains("Timeless") && nEquip.getItemLevel() < 6) {
nEquip.gainItemExp(client, mobexp, itemName.contains("Reverse"));
if ((nEquip.getItemLevel() < ServerConstants.USE_EQUIPMNT_LVLUP) || (itemName.contains("Reverse") && nEquip.getItemLevel() < 4) || (itemName.contains("Timeless") && nEquip.getItemLevel() < 6)) {
nEquip.gainItemExp(client, expGain);
}
}
}

View File

@@ -103,7 +103,7 @@ public class MapleMount {
if (tiredness > 99) {
this.tiredness = 99;
owner.dispelSkill(owner.getJobType() * 10000000 + 1004);
owner.dropMessage("Your mount grew tired! Treat it some revitalizer before riding it again!");
owner.dropMessage(6, "Your mount grew tired! Treat it some revitalizer before riding it again!");
}
} else {
if(this.tirednessSchedule != null) {

View File

@@ -648,28 +648,28 @@ public class Commands {
//debug only
case "debugpos":
if(ServerConstants.USE_DEBUG) {
player.dropMessage("Current map position: (" + player.getPosition().getX() + ", " + player.getPosition().getY() + ").");
player.dropMessage(6, "Current map position: (" + player.getPosition().getX() + ", " + player.getPosition().getY() + ").");
}
break;
case "debugmap":
if(ServerConstants.USE_DEBUG) {
player.dropMessage("Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ".");
player.dropMessage(6, "Current map id " + player.getMap().getId() + ", event: '" + ((player.getMap().getEventInstance() != null) ? player.getMap().getEventInstance().getName() : "null") + "'; Players: " + player.getMap().getAllPlayers().size() + ", Mobs: " + player.getMap().countMonsters() + ", Reactors: " + player.getMap().countReactors() + ".");
}
break;
case "debugevent":
if(ServerConstants.USE_DEBUG) {
if(player.getEventInstance() == null) player.dropMessage("Player currently not in an event.");
else player.dropMessage("Current event name: " + player.getEventInstance().getName() + ".");
if(player.getEventInstance() == null) player.dropMessage(6, "Player currently not in an event.");
else player.dropMessage(6, "Current event name: " + player.getEventInstance().getName() + ".");
}
break;
case "debugreactors":
if(ServerConstants.USE_DEBUG) {
player.dropMessage("Current reactor states on map " + player.getMapId() + ":");
player.dropMessage(6, "Current reactor states on map " + player.getMapId() + ":");
for(Pair p: player.getMap().reportReactorStates()) {
player.dropMessage("Reactor id: " + p.getLeft() + " -> State: " + p.getRight() + ".");
player.dropMessage(6, "Reactor id: " + p.getLeft() + " -> State: " + p.getRight() + ".");
}
}
break;
@@ -682,7 +682,7 @@ public class Commands {
s += (i + " ");
}
player.dropMessage(s);
player.dropMessage(6, s);
}
break;
@@ -693,7 +693,7 @@ public class Commands {
s += (i + " ");
}
player.dropMessage(s);
player.dropMessage(6, s);
}
break;

View File

@@ -22,11 +22,14 @@
package client.inventory;
import client.MapleClient;
import constants.ServerConstants;
import constants.ExpTable;
import java.util.LinkedList;
import java.util.List;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.Randomizer;
public class Equip extends Item {
@@ -49,11 +52,10 @@ public class Equip extends Item {
private float itemExp;
private int ringid = -1;
private boolean wear = false;
private boolean isElemental = false; // timeless or reverse
public Equip(int id, short position) {
super(id, position, (short) 1);
this.itemExp = 0;
this.itemLevel = 1;
this(id, position, 0);
}
public Equip(int id, short position, int slots) {
@@ -61,6 +63,9 @@ public class Equip extends Item {
this.upgradeSlots = (byte) slots;
this.itemExp = 0;
this.itemLevel = 1;
String itemName = MapleItemInformationProvider.getInstance().getName(id);
if(itemName != null) this.isElemental = (itemName.contains("Timeless") || itemName.contains("Reverse"));
}
@Override
@@ -254,8 +259,59 @@ public class Equip extends Item {
this.level = level;
}
public void gainLevel(MapleClient c, boolean timeless) {
List<Pair<String, Integer>> stats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel, timeless);
private int getStatModifier(boolean isAttribute) {
if(ServerConstants.USE_EQUIPMNT_LVLUP_POWER) {
if(isAttribute) return 2;
else return 4;
}
else {
if(isAttribute) return 4;
else return 16;
}
}
private void getUnitStatUpgrade(List<Pair<String, Integer>> stats, String name, int curStat, boolean isAttribute) {
int maxUpgrade = Randomizer.rand(0, 1 + (curStat / getStatModifier(isAttribute)));
if(maxUpgrade == 0) return;
stats.add(new Pair<>(name, maxUpgrade)); // each 4 stat point grants a bonus stat upgrade on equip level up.
}
private void getUnitSlotUpgrade(List<Pair<String, Integer>> stats, String 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);
}
public void gainLevel(MapleClient c) {
List<Pair<String, Integer>> stats = MapleItemInformationProvider.getInstance().getItemLevelupStats(getItemId(), itemLevel);
if(stats.isEmpty()) improveDefaultStats(stats);
if(ServerConstants.USE_EQUIPMNT_LVLUP_SLOTS) {
getUnitSlotUpgrade(stats, "incVicious");
getUnitSlotUpgrade(stats, "incSlot");
}
itemLevel++;
if(ServerConstants.USE_DEBUG) c.getPlayer().dropMessage(6, "'" + MapleItemInformationProvider.getInstance().getName(this.getItemId()) + "' has LEVELED UP to level " + itemLevel + "!");
for (Pair<String, Integer> stat : stats) {
switch (stat.getLeft()) {
case "incDEX":
@@ -300,9 +356,22 @@ public class Equip extends Item {
case "incJump":
jump += stat.getRight();
break;
case "incVicious":
if(vicious > 0) {
vicious -= stat.getRight();
if(vicious < 0) vicious = 0;
c.getPlayer().dropMessage(6, "A new Vicious Hammer opportunity has been found on the '" + MapleItemInformationProvider.getInstance().getName(getItemId()) + "'!");
}
break;
case "incSlot":
upgradeSlots += stat.getRight();
c.getPlayer().dropMessage(6, "A new upgrade slot has been found on the '" + MapleItemInformationProvider.getInstance().getName(getItemId()) + "'!");
break;
}
}
this.itemLevel++;
c.announce(MaplePacketCreator.showEquipmentLevelUp());
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeignEffect(c.getPlayer().getId(), 15));
c.getPlayer().forceUpdateItem(this);
@@ -311,17 +380,41 @@ public class Equip extends Item {
public int getItemExp() {
return (int) itemExp;
}
private double normalizedMasteryExp(int reqLevel) {
return Math.max((2622.71 * Math.exp(reqLevel * 0.0533649)) - 6000.0, 15);
}
public void gainItemExp(MapleClient c, int gain) { // Ronan's Equip Exp gain method
if(itemLevel >= 30) return;
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 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);
if (itemExp >= expNeeded) {
while(itemExp >= expNeeded) {
itemExp = (itemExp - expNeeded);
gainLevel(c);
public void gainItemExp(MapleClient c, int gain, boolean reverse) {
int expneeded = !reverse ? (10 * itemLevel + 70) : (5 * itemLevel + 65);
float modifier = 364 / expneeded;
float exp = (expneeded / (1000000 * modifier * modifier)) * gain;
itemExp += exp;
if (itemExp >= 364) {
itemExp = (itemExp - 364);
gainLevel(c, !reverse);
if(itemLevel == ServerConstants.USE_EQUIPMNT_LVLUP) {
itemExp = 0.0f;
break;
}
expNeeded = ExpTable.getEquipExpNeededForLevel(itemLevel);
}
} else {
c.getPlayer().forceUpdateItem(this);
//if(ServerConstants.USE_DEBUG) c.getPlayer().dropMessage("'" + MapleItemInformationProvider.getInstance().getName(this.getItemId()) + "': " + itemExp + " / " + expNeeded);
}
}

View File

@@ -23,6 +23,7 @@ package constants;
public final class ExpTable {
private static final int[] exp = {1, 15, 34, 57, 92, 135, 372, 560, 840, 1144, 1242, 1573, 2144, 2800, 3640, 4700, 5893, 7360, 9144, 11120, 13477, 16268, 19320, 22880, 27008, 31477, 36600, 42444, 48720, 55813, 63800, 86784, 98208, 110932, 124432, 139372, 155865, 173280, 192400, 213345, 235372, 259392, 285532, 312928, 342624, 374760, 408336, 445544, 483532, 524160, 567772, 598886, 631704, 666321, 702836, 741351, 781976, 824828, 870028, 917625, 967995, 1021041, 1076994, 1136013, 1198266, 1263930, 1333194, 1406252, 1483314, 1564600, 1650340, 1740778, 1836173, 1936794, 2042930, 2154882, 2272970, 2397528, 2528912, 2667496, 2813674, 2967863, 3130502, 3302053, 3483005, 3673873, 3875201, 4087562, 4311559, 4547832, 4797053, 5059931, 5337215, 5629694, 5938202, 6263614, 6606860, 6968915, 7350811, 7753635, 8178534, 8626718, 9099462, 9598112, 10124088, 10678888, 11264090, 11881362, 12532461, 13219239, 13943653, 14707765, 15513750, 16363902, 17260644, 18206527, 19204245, 20256637, 21366700, 22537594, 23772654, 25075395, 26449526, 27898960, 29427822, 31040466, 32741483, 34535716, 36428273, 38424542, 40530206, 42751262, 45094030, 47565183, 50171755, 52921167, 55821246, 58880250, 62106888, 65510344, 69100311, 72887008, 76881216, 81094306, 85594273, 90225770, 95170142, 100385466, 105886589, 111689174, 117809740, 124265714, 131075474, 138258410, 145834970, 153826726, 162256430, 171148082, 180526997, 190419876, 200854885, 211861732, 223471711, 223471711, 248635353, 262260570, 276632449, 291791906, 307782102, 324648562, 342439302, 361204976, 380999008, 401877754, 423900654, 447130410, 471633156, 497478653, 524740482, 553496261, 583827855, 615821622, 649568646, 685165008, 722712050, 762316670, 804091623, 848155844, 894634784, 943660770, 995373379, 1049919840, 1107455447, 1168144006, 1232158297, 1299680571, 1370903066, 1446028554, 1525246918, 1608855764, 1697021059};
private static final int[] equip = {1, 15, 19, 23, 35, 43, 98, 188, 237, 280, 304, 331, 571, 656, 840, 1060, 1193, 1467, 1784, 1976, 2357, 2791, 3052, 3560, 4128, 4469, 5123, 5844, 6276, 7093};
private static final int[] pet = {1, 1, 3, 6, 14, 31, 60, 108, 181, 287, 434, 632, 891, 1224, 1642, 2161, 2793, 3557, 4467, 5542, 6801, 8263, 9950, 11882, 14084, 16578, 19391, 22547, 26074, 30000, 2147483647};
private static final int[] mount = {1, 24, 50, 105, 134, 196, 254, 263, 315, 367, 430, 543, 587, 679, 725, 897, 1146, 1394, 1701, 2247, 2543, 2898, 3156, 3313, 3584, 3923, 4150, 4305, 4550};
@@ -37,4 +38,8 @@ public final class ExpTable {
public static int getMountExpNeededForLevel(int level) {
return mount[level];
}
public static int getEquipExpNeededForLevel(int level) {
return level > 30 ? 2000000000 : exp[level];
}
}

View File

@@ -7,6 +7,23 @@ import constants.skills.Aran;
* @author kevintjuh93
*/
public class GameConstants {
// Ronan's rates upgrade system
private static final int[] DROP_RATE_GAIN = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
private static final int[] MESO_RATE_GAIN = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66};
private static final int[] EXP_RATE_GAIN = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}; //fibonacci :3
public static int getPlayerBonusMesoRate(int slot) {
return(MESO_RATE_GAIN[slot]);
}
public static int getPlayerBonusDropRate(int slot) {
return(DROP_RATE_GAIN[slot]);
}
public static int getPlayerBonusExpRate(int slot) {
return(EXP_RATE_GAIN[slot]);
}
private static final int[] mobHpVal = {0, 15, 20, 25, 35, 50, 65, 80, 95, 110, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350,
375, 405, 435, 465, 495, 525, 580, 650, 720, 790, 900, 990, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800,
1900, 2000, 2100, 2200, 2300, 2400, 2520, 2640, 2760, 2880, 3000, 3200, 3400, 3600, 3800, 4000, 4300, 4600, 4900, 5200,

View File

@@ -58,7 +58,9 @@ public class ServerConstants {
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 int USE_EQUIPMNT_LVLUP = 7; //Nope, not working yet. //all equips lvlup at max level as N, set 0 to disable.
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 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.
@@ -70,8 +72,8 @@ public class ServerConstants {
public static final boolean USE_DEADLY_DOJO = false; //Should bosses really use 1HP,1MP attacks in dojo?
//Pet Hungry Configuration
public static final boolean PETS_NEVER_HUNGRY = false; //If true, pets will never grow hungry.
public static final boolean GM_PETS_NEVER_HUNGRY = true; //If true, pets of GMs will never grow hungry.
public static final boolean PETS_NEVER_HUNGRY = false; //If true, pets and mounts will never grow hungry.
public static final boolean GM_PETS_NEVER_HUNGRY = true; //If true, pets and mounts owned by GMs will never grow hungry.
//Rates And Experience
public static final int EXP_RATE = 10;

View File

@@ -1453,20 +1453,11 @@ public class MapleItemInformationProvider {
return ret;
}
public List<Pair<String, Integer>> getItemLevelupStats(int itemId, int level, boolean timeless) {
public List<Pair<String, Integer>> getItemLevelupStats(int itemId, int level) {
List<Pair<String, Integer>> list = new LinkedList<>();
MapleData data = getItemData(itemId);
MapleData data1 = data.getChildByPath("info").getChildByPath("level");
/*if ((timeless && level == 5) || (!timeless && level == 3)) {
MapleData skilldata = data1.getChildByPath("case").getChildByPath("1").getChildByPath(timeless ? "6" : "4");
if (skilldata != null) {
List<MapleData> skills = skilldata.getChildByPath("Skill").getChildren();
for (int i = 0; i < skilldata.getChildByPath("Skill").getChildren().size(); i++) {
System.out.println(MapleDataTool.getInt(skills.get(i).getChildByPath("id")));
if (Math.random() < 0.1) list.add(new Pair<String, Integer>("Skill" + 0, MapleDataTool.getInt(skills.get(i).getChildByPath("id"))));
}
}
}*/
if (data1 != null) {
MapleData data2 = data1.getChildByPath("info").getChildByPath(Integer.toString(level));
if (data2 != null) {

View File

@@ -372,7 +372,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
attacker.gainExp(personalExp, partyExp, true, false, isKiller);
attacker.mobKilled(getId());
attacker.increaseEquipExp(personalExp);//better place
attacker.increaseEquipExp(personalExp);
}
}