Dynamic World/Channel shutdown + Equip levels on Duey + AP/SP patch

Implemented dynamic world/channel shutdown, coupling with the dynamic deployment from last commit rendering on a fully automated world/channel management.
Fixed some spawned mobs not being properly registered on events.
Implemented a respawn mechanic sensitive to number of players on map. More mobs will spawn the greater the number of players is. Server flag: USE_ENABLE_FULL_RESPAWN = false.
Implemented a mechanic for delayed mob loot drops, on which the delay is determined by the death animation duration. Server flag: USE_SPAWN_LOOT_ON_ANIMATION = true.
Fixed EIM being disposed incorrectly when the dispose is called through scripts.
Protected concurrently AP and SP distribution handlers.
Slightly improved HealOvertimeHandler performance.
Fixed Duey not propagating equipment level and experience when transfering items.
Buyback now has a short grace period, granting the returning player time for decision making (players won't die right away, rather sticks at 1HP).
Reviewed item monitor task not properly protected concurrently.
Fixed some issues with ropes on some Kampung Village maps.
Fixed "maxhpmp" command allowing to pass negative values.
This commit is contained in:
ronancpl
2018-07-28 22:00:52 -03:00
parent 8aadf7c369
commit cc541f39d5
77 changed files with 33492 additions and 32661 deletions

View File

@@ -23,8 +23,6 @@ package net.server.channel.handlers;
import client.MapleCharacter;
import client.MapleClient;
import client.MapleJob;
import client.MapleStat;
import client.Skill;
import client.SkillFactory;
import client.creator.veteran.*;
@@ -36,6 +34,7 @@ import client.inventory.MaplePet;
import client.inventory.ModifyInventory;
import client.inventory.manipulator.MapleInventoryManipulator;
import client.inventory.manipulator.MapleKarmaManipulator;
import client.processor.AssignAPProcessor;
import constants.GameConstants;
import constants.ItemConstants;
import constants.ServerConstants;
@@ -79,9 +78,9 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
slea.readShort();
int itemId = slea.readInt();
int itemType = itemId / 10000;
Item toUse = c.getPlayer().getInventory(MapleInventoryType.CASH).getItem(c.getPlayer().getInventory(MapleInventoryType.CASH).findById(itemId).getPosition());
Item toUse = player.getInventory(MapleInventoryType.CASH).getItem(player.getInventory(MapleInventoryType.CASH).findById(itemId).getPosition());
String medal = "";
Item medalItem = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -49);
Item medalItem = player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -49);
if (medalItem != null) {
medal = "<" + ii.getName(medalItem.getItemId()) + "> ";
}
@@ -100,7 +99,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
player.changeMap(c.getChannelServer().getMapFactory().getMap(mapId));
} else {
MapleInventoryManipulator.addById(c, itemId, (short) 1);
c.getPlayer().dropMessage(1, error1);
player.dropMessage(1, error1);
c.announce(MaplePacketCreator.enableActions());
}
} else {
@@ -149,131 +148,12 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
player.changeSkillLevel(skillSPTo, (byte) (curLevel + 1), player.getMasterLevel(skillSPTo), -1);
}
} else {
List<Pair<MapleStat, Integer>> statupdate = new ArrayList<>(2);
int APTo = slea.readInt();
int APFrom = slea.readInt();
switch (APFrom) {
case 64: // str
if (player.getStr() < 5) {
c.getPlayer().message("You don't have the minimum STR required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.addStat(1, -1);
break;
case 128: // dex
if (player.getDex() < 5) {
c.getPlayer().message("You don't have the minimum DEX required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.addStat(2, -1);
break;
case 256: // int
if (player.getInt() < 5) {
c.getPlayer().message("You don't have the minimum INT required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.addStat(3, -1);
break;
case 512: // luk
if (player.getLuk() < 5) {
c.getPlayer().message("You don't have the minimum LUK required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.addStat(4, -1);
break;
case 2048: // HP
if(ServerConstants.USE_ENFORCE_HPMP_SWAP) {
if (APTo != 8192) {
c.getPlayer().message("You can only swap HP ability points to MP.");
c.announce(MaplePacketCreator.enableActions());
return;
}
}
if (player.getHpMpApUsed() < 1) {
c.getPlayer().message("You don't have enough HPMP stat points to spend on AP Reset.");
c.announce(MaplePacketCreator.enableActions());
return;
}
int hp = player.getMaxHp();
int level_ = player.getLevel();
boolean canWash_ = true;
if (hp < level_ * 14 + 148) {
canWash_ = false;
}
if (!canWash_) {
c.getPlayer().message("You don't have the minimum HP pool required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.setHpMpApUsed(player.getHpMpApUsed() - 1);
int hplose = -DistributeAPHandler.takeHp(player, player.getJob());
int nextHp = Math.max(1, player.getHp() + hplose), nextMaxHp = Math.max(50, player.getMaxHp() + hplose);
player.setHp(nextHp);
player.setMaxHp(nextMaxHp);
statupdate.add(new Pair<>(MapleStat.HP, nextHp));
statupdate.add(new Pair<>(MapleStat.MAXHP, nextMaxHp));
break;
case 8192: // MP
if(ServerConstants.USE_ENFORCE_HPMP_SWAP) {
if (APTo != 2048) {
c.getPlayer().message("You can only swap MP ability points to HP.");
c.announce(MaplePacketCreator.enableActions());
return;
}
}
if (player.getHpMpApUsed() < 1) {
c.getPlayer().message("You don't have enough HPMP stat points to spend on AP Reset.");
c.announce(MaplePacketCreator.enableActions());
return;
}
int mp = player.getMaxMp();
int level = player.getLevel();
MapleJob job = player.getJob();
boolean canWash = true;
if (job.isA(MapleJob.SPEARMAN) && mp < 4 * level + 156) {
canWash = false;
} else if (job.isA(MapleJob.FIGHTER) && mp < 4 * level + 56) {
canWash = false;
} else if (job.isA(MapleJob.THIEF) && job.getId() % 100 > 0 && mp < level * 14 - 4) {
canWash = false;
} else if (mp < level * 14 + 148) {
canWash = false;
}
if (!canWash) {
c.getPlayer().message("You don't have the minimum MP pool required to swap.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.setHpMpApUsed(player.getHpMpApUsed() - 1);
int mplose = -DistributeAPHandler.takeMp(player, job);
int nextMp = Math.max(0, player.getMp() + mplose), nextMaxMp = Math.max(5, player.getMaxMp() + mplose);
player.setMp(nextMp);
player.setMaxMp(nextMaxMp);
statupdate.add(new Pair<>(MapleStat.MP, nextMp));
statupdate.add(new Pair<>(MapleStat.MAXMP, nextMaxMp));
break;
default:
c.announce(MaplePacketCreator.updatePlayerStats(MaplePacketCreator.EMPTY_STATUPDATE, true, c.getPlayer()));
return;
if(!AssignAPProcessor.APResetAction(c, APFrom, APTo)) {
return;
}
DistributeAPHandler.addStat(c, APTo, true);
c.announce(MaplePacketCreator.updatePlayerStats(statupdate, true, c.getPlayer()));
}
remove(c, itemId);
} else if (itemType == 506) {
@@ -287,7 +167,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
eq.setOwner(player.getName());
} else if (itemId == 5060001 || itemId == 5061000 || itemId == 5061001 || itemId == 5061002 || itemId == 5061003) { // Sealing lock
MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
eq = c.getPlayer().getInventory(type).getItem((short) slea.readInt());
eq = player.getInventory(type).getItem((short) slea.readInt());
if (eq == null) { //Check if the type is EQUIPMENT?
return;
}
@@ -317,7 +197,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
} else if (itemId == 5060002) { // Incubator
byte inventory2 = (byte) slea.readInt();
short slot2 = (short) slea.readInt();
Item item2 = c.getPlayer().getInventory(MapleInventoryType.getByType(inventory2)).getItem(slot2);
Item item2 = player.getInventory(MapleInventoryType.getByType(inventory2)).getItem(slot2);
if (item2 == null) // hacking
{
return;
@@ -388,11 +268,11 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
break;
case 6: //item megaphone
String msg = medal + c.getPlayer().getName() + " : " + slea.readMapleAsciiString();
String msg = medal + player.getName() + " : " + slea.readMapleAsciiString();
whisper = slea.readByte() == 1;
Item item = null;
if (slea.readByte() == 1) { //item
item = c.getPlayer().getInventory(MapleInventoryType.getByType((byte) slea.readInt())).getItem((short) slea.readInt());
item = player.getInventory(MapleInventoryType.getByType((byte) slea.readInt())).getItem((short) slea.readInt());
if (item == null) //hack
{
return;
@@ -412,7 +292,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
String[] msg2 = new String[lines];
for (int i = 0; i < lines; i++) {
msg2[i] = medal + c.getPlayer().getName() + " : " + slea.readMapleAsciiString();
msg2[i] = medal + player.getName() + " : " + slea.readMapleAsciiString();
}
whisper = slea.readByte() == 1;
Server.getInstance().broadcastMessage(c.getWorld(), MaplePacketCreator.getMultiMegaphone(msg2, c.getChannel(), whisper));
@@ -420,10 +300,10 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
remove(c, itemId);
} else if (itemType == 508) { // graduation banner, thanks to tmskdl12
MapleKite kite = new MapleKite(c.getPlayer(), slea.readMapleAsciiString(), itemId);
MapleKite kite = new MapleKite(player, slea.readMapleAsciiString(), itemId);
if (!GameConstants.isFreeMarketRoom(c.getPlayer().getMapId())) {
c.getPlayer().getMap().spawnKite(kite);
if (!GameConstants.isFreeMarketRoom(player.getMapId())) {
player.getMap().spawnKite(kite);
remove(c, itemId);
} else {
c.announce(MaplePacketCreator.sendCannotSpawnKite());
@@ -442,11 +322,11 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
remove(c, itemId);
} else if (itemType == 512) {
if (ii.getStateChangeItem(itemId) != 0) {
for (MapleCharacter mChar : c.getPlayer().getMap().getCharacters()) {
for (MapleCharacter mChar : player.getMap().getCharacters()) {
ii.getItemEffect(ii.getStateChangeItem(itemId)).applyTo(mChar);
}
}
player.getMap().startMapEffect(ii.getMsg(itemId).replaceFirst("%s", c.getPlayer().getName()).replaceFirst("%s", slea.readMapleAsciiString()), itemId);
player.getMap().startMapEffect(ii.getMsg(itemId).replaceFirst("%s", player.getName()).replaceFirst("%s", slea.readMapleAsciiString()), itemId);
remove(c, itemId);
} else if (itemType == 517) {
MaplePet pet = player.getPet(0);
@@ -512,7 +392,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
final int world = c.getWorld();
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(c.getPlayer(), medal, c.getChannel(), itemId, strLines, (slea.readByte() != 0)));
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(player, medal, c.getChannel(), itemId, strLines, (slea.readByte() != 0)));
TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
@@ -585,20 +465,20 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
} else if (itemType == 552) {
MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
short slot = (short) slea.readInt();
Item item = c.getPlayer().getInventory(type).getItem(slot);
Item item = player.getInventory(type).getItem(slot);
if (item == null || item.getQuantity() <= 0 || MapleKarmaManipulator.hasKarmaFlag(item) || !ii.isKarmaAble(item.getItemId())) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if(MapleKarmaManipulator.hasUsedKarmaFlag(item)) {
c.getPlayer().dropMessage(6, "Scissors of Karma was already used on this item.");
player.dropMessage(6, "Scissors of Karma was already used on this item.");
c.announce(MaplePacketCreator.enableActions());
return;
}
MapleKarmaManipulator.setKarmaFlag(item);
c.getPlayer().forceUpdateItem(item);
player.forceUpdateItem(item);
remove(c, itemId);
c.announce(MaplePacketCreator.enableActions());
} else if (itemType == 552) { //DS EGG THING
@@ -607,8 +487,8 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
slea.readInt();
int itemSlot = slea.readInt();
slea.readInt();
final Equip equip = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((short) itemSlot);
if (equip.getVicious() == 2 || c.getPlayer().getInventory(MapleInventoryType.CASH).findById(5570000) == null) {
final Equip equip = (Equip) player.getInventory(MapleInventoryType.EQUIP).getItem((short) itemSlot);
if (equip.getVicious() == 2 || player.getInventory(MapleInventoryType.CASH).findById(5570000) == null) {
return;
}
equip.setVicious(equip.getVicious() + 1);
@@ -623,14 +503,14 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
final byte eSlot = (byte) slea.readInt();
final Item eitem = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(eSlot);
final Item eitem = player.getInventory(MapleInventoryType.EQUIP).getItem(eSlot);
if (slea.readInt() != 2) {
return;
}
final byte uSlot = (byte) slea.readInt();
final Item uitem = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(uSlot);
final Item uitem = player.getInventory(MapleInventoryType.USE).getItem(uSlot);
if (eitem == null || uitem == null) {
return;
}
@@ -644,12 +524,12 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
//should have a check here against PE hacks
if(itemId / 1000000 != 5) itemId = 0;
c.getPlayer().toggleBlockCashShop();
player.toggleBlockCashShop();
final int curlevel = toScroll.getLevel();
c.getSession().write(MaplePacketCreator.sendVegaScroll(0x40));
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, c.getPlayer().isGM());
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, player.isGM());
c.getSession().write(MaplePacketCreator.sendVegaScroll(scrolled.getLevel() > curlevel ? 0x41 : 0x43));
//opcodes 0x42, 0x44: "this item cannot be used"; 0x39, 0x45: crashes