Heal GMS + Improved chnl workers & Pshop tooltip + Equips on party HP
Slightly improved channel and disease announce workers performance. Completion of repeatable quests no longer generates fame to players. Equipment drop rates of Leprechaun were slightly decreased. Fixed Pet Item Ignore not checking certain exploit cases correctly. Optimized Pet Item Ignore server handler performance. Fixed some exploits and improved performance on PetLootHandler. Improved concurrency protection on MapleInventoryManipulator. Heal skill effect on players now works GMS-intended, as description says. Also removed the delayed Heal cast effect to others. Fixed party player HPBar not accounting the player's HP stat gained on equips towards the effective MaxHP. The duration of mists generated by mobs has been rescaled to 10x longer than what has been displayed until now (wz duration property is supposed to actually be in 100ms). Optimized timer management for mob skill cooldown and elemental effectiveness. Implemented an additional inventory check system, to be used in cases where it's expected to remove a set group for items (with quantity) to then add a new group of items. Fixed Player Shop/Hired Merchant "vacancy" tooltip, now properly showing whether the store has a visitor room or is already full at that time. Fixed Player Shops only using the standard stand type. Fixed cash pet food ignoring certain pet itemids when reading data from WZ.
This commit is contained in:
@@ -64,7 +64,6 @@ import net.server.world.PartyOperation;
|
||||
import net.server.world.World;
|
||||
import scripting.event.EventInstanceManager;
|
||||
import server.CashShop;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MaplePortal;
|
||||
import server.MapleShop;
|
||||
@@ -104,7 +103,6 @@ import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.Randomizer;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import tools.packets.Wedding;
|
||||
import client.autoban.AutobanManager;
|
||||
import client.creator.CharacterFactoryRecipe;
|
||||
@@ -112,11 +110,13 @@ import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryProof;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import client.inventory.MaplePet;
|
||||
import client.inventory.MapleWeaponType;
|
||||
import client.inventory.ModifyInventory;
|
||||
import client.inventory.PetDataFactory;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import client.newyear.NewYearCardRecord;
|
||||
import constants.ExpTable;
|
||||
import constants.GameConstants;
|
||||
@@ -156,7 +156,8 @@ import constants.skills.ThunderBreaker;
|
||||
import net.server.channel.handlers.PartyOperationHandler;
|
||||
import scripting.item.ItemScriptManager;
|
||||
import server.maps.MapleMapItem;
|
||||
import tools.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
|
||||
public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
@@ -168,7 +169,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private int world;
|
||||
private int accountid, id;
|
||||
private int rank, rankMove, jobRank, jobRankMove;
|
||||
private int level, str, dex, luk, int_, hp, maxhp, mp, maxmp;
|
||||
private int level, str, dex, luk, int_, hp, maxhp, eqphp, mp, maxmp, eqpmp;
|
||||
private int hpMpApUsed;
|
||||
private int hair;
|
||||
private int face;
|
||||
@@ -202,6 +203,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private long lastfametime, lastUsedCashItem, lastExpression = 0, lastHealed, lastBuyback = 0, lastDeathtime, lastMesoDrop = -1, jailExpiration = -1;
|
||||
private transient int localmaxhp, localmaxmp, localstr, localdex, localluk, localint_, magic, watk;
|
||||
private boolean hidden, canDoor = true, berserk, hasMerchant, hasSandboxItem = false, whiteChat = false;
|
||||
private boolean equippedMesoMagnet = false, equippedItemPouch = false, equippedPetItemIgnore = false;
|
||||
private int linkedLevel = 0;
|
||||
private String linkedName = null;
|
||||
private boolean finishedDojoTutorial;
|
||||
@@ -325,6 +327,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
for (int i = 0; i < remainingSp.length; i++) {
|
||||
remainingSp[i] = 0;
|
||||
}
|
||||
|
||||
for (MapleInventoryType type : MapleInventoryType.values()) {
|
||||
byte b = 24;
|
||||
if (type == MapleInventoryType.CASH) {
|
||||
@@ -332,6 +335,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
inventory[type.ordinal()] = new MapleInventory(this, type, (byte) b);
|
||||
}
|
||||
inventory[MapleInventoryType.CANHOLD.ordinal()] = new MapleInventoryProof(this);
|
||||
|
||||
for (int i = 0; i < SavedLocationType.values().length; i++) {
|
||||
savedLocations[i] = null;
|
||||
}
|
||||
@@ -4392,6 +4397,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public int getMaxHp() {
|
||||
return maxhp;
|
||||
}
|
||||
|
||||
public int getMaxMp() {
|
||||
return maxmp;
|
||||
}
|
||||
|
||||
public int getMaxHpEquipped() {
|
||||
return Math.min(maxhp + eqphp, 30000);
|
||||
}
|
||||
|
||||
public int getMaxMpEquipped() {
|
||||
return Math.min(maxmp + eqpmp, 30000);
|
||||
}
|
||||
|
||||
public int getMaxClassLevel() {
|
||||
return isCygnus() ? 120 : 200;
|
||||
@@ -4404,11 +4421,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
|
||||
return GameConstants.getJobMaxLevel(job);
|
||||
}
|
||||
|
||||
public int getMaxMp() {
|
||||
return maxmp;
|
||||
}
|
||||
|
||||
|
||||
public int getMeso() {
|
||||
return meso.get();
|
||||
}
|
||||
@@ -4693,7 +4706,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
|
||||
this.setMiniGame(null);
|
||||
if (game.isOwner(this)) {
|
||||
this.getMap().broadcastMessage(MaplePacketCreator.removeCharBox(this));
|
||||
this.getMap().broadcastMessage(MaplePacketCreator.removeMinigameBox(this));
|
||||
game.broadcastToVisitor(MaplePacketCreator.getMiniGameClose(3));
|
||||
} else {
|
||||
game.removeVisitor(this);
|
||||
@@ -5176,8 +5189,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ps.setInt(1, getId());
|
||||
ps.setInt(2, to.getId());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
@@ -6610,7 +6622,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (partychar.getMapId() == mapId && partychar.getChannel() == channel) {
|
||||
MapleCharacter other = Server.getInstance().getWorld(world).getChannel(channel).getPlayerStorage().getCharacterByName(partychar.getName());
|
||||
if (other != null) {
|
||||
client.announce(MaplePacketCreator.updatePartyMemberHP(other.getId(), other.getHp(), other.getCurrentMaxHp()));
|
||||
client.announce(MaplePacketCreator.updatePartyMemberHP(other.getId(), other.getHp(), other.getMaxHpEquipped()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7388,7 +7400,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ps.setString(1, to);
|
||||
ps.setString(2, this.getName());
|
||||
ps.setString(3, msg);
|
||||
ps.setLong(4, System.currentTimeMillis());
|
||||
ps.setLong(4, Server.getInstance().getCurrentTime());
|
||||
ps.setByte(5, fame);
|
||||
ps.executeUpdate();
|
||||
} finally {
|
||||
@@ -8149,11 +8161,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
int channel = client.getChannel();
|
||||
int mapId = getMapId();
|
||||
|
||||
int curmaxhp = getMaxHpEquipped();
|
||||
for (MaplePartyCharacter partychar : party.getMembers()) {
|
||||
if (partychar.getMapId() == mapId && partychar.getChannel() == channel) {
|
||||
MapleCharacter other = Server.getInstance().getWorld(world).getChannel(channel).getPlayerStorage().getCharacterByName(partychar.getName());
|
||||
if (other != null) {
|
||||
other.client.announce(MaplePacketCreator.updatePartyMemberHP(getId(), this.hp, maxhp));
|
||||
other.client.announce(MaplePacketCreator.updatePartyMemberHP(getId(), this.hp, curmaxhp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8202,8 +8215,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
announce(MaplePacketCreator.updateQuestInfo((short) quest.getQuest().getId(), quest.getNpc()));
|
||||
} else if (quest.getStatus().equals(MapleQuestStatus.Status.COMPLETED)) {
|
||||
short questid = quest.getQuest().getId();
|
||||
if(!MapleQuest.isExploitableQuest(questid)) {
|
||||
MapleQuest mquest = quest.getQuest();
|
||||
short questid = mquest.getId();
|
||||
if(!mquest.isSameDayRepeatable() && !MapleQuest.isExploitableQuest(questid)) {
|
||||
quest_fame += 1;
|
||||
if(ServerConstants.FAME_GAIN_BY_QUEST > 0)
|
||||
fameGainByQuest();
|
||||
@@ -8679,7 +8693,56 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return autoban;
|
||||
}
|
||||
|
||||
public void equipPendantOfSpirit() {
|
||||
public void resetEquippedHpMp() {
|
||||
eqphp = 0;
|
||||
eqpmp = 0;
|
||||
}
|
||||
|
||||
public void equippedItem(Equip equip) {
|
||||
int itemid = equip.getItemId();
|
||||
eqphp += equip.getHp();
|
||||
eqpmp += equip.getMp();
|
||||
|
||||
if (itemid == 1122017) {
|
||||
this.equipPendantOfSpirit();
|
||||
} else if (itemid == 1812000) { // meso magnet
|
||||
equippedMesoMagnet = true;
|
||||
} else if (itemid == 1812001) { // item pouch
|
||||
equippedItemPouch = true;
|
||||
} else if (itemid == 1812007) { // item ignore pendant
|
||||
equippedPetItemIgnore = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void unequippedItem(Equip equip) {
|
||||
int itemid = equip.getItemId();
|
||||
eqphp -= equip.getHp();
|
||||
eqpmp -= equip.getMp();
|
||||
|
||||
if (itemid == 1122017) {
|
||||
this.unequipPendantOfSpirit();
|
||||
} else if (itemid == 1812000) { // meso magnet
|
||||
equippedMesoMagnet = false;
|
||||
} else if (itemid == 1812001) { // item pouch
|
||||
equippedItemPouch = false;
|
||||
} else if (itemid == 1812007) { // item ignore pendant
|
||||
equippedPetItemIgnore = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEquippedMesoMagnet() {
|
||||
return equippedMesoMagnet;
|
||||
}
|
||||
|
||||
public boolean isEquippedItemPouch() {
|
||||
return equippedItemPouch;
|
||||
}
|
||||
|
||||
public boolean isEquippedPetItemIgnore() {
|
||||
return equippedPetItemIgnore;
|
||||
}
|
||||
|
||||
private void equipPendantOfSpirit() {
|
||||
if (pendantOfSpirit == null) {
|
||||
pendantOfSpirit = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
@@ -8695,7 +8758,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void unequipPendantOfSpirit() {
|
||||
private void unequipPendantOfSpirit() {
|
||||
if (pendantOfSpirit != null) {
|
||||
pendantOfSpirit.cancel(false);
|
||||
pendantOfSpirit = null;
|
||||
|
||||
@@ -44,7 +44,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import tools.*;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
@@ -74,7 +73,9 @@ import server.life.MapleMonster;
|
||||
import server.MapleTrade;
|
||||
import server.maps.*;
|
||||
import server.quest.MapleQuest;
|
||||
import tools.locks.MonitoredLockType;
|
||||
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
|
||||
public class MapleClient {
|
||||
|
||||
@@ -793,20 +794,19 @@ public class MapleClient {
|
||||
try {
|
||||
player.setAwayFromWorld(true);
|
||||
player.notifyMapTransferToPartner(-1);
|
||||
player.cancelAllBuffs(true);
|
||||
player.cancelAllDebuffs();
|
||||
player.cancelAllBuffs(true);
|
||||
player.cancelAllDebuffs();
|
||||
|
||||
player.closePlayerInteractions();
|
||||
QuestScriptManager.getInstance().dispose(this);
|
||||
QuestScriptManager.getInstance().dispose(this);
|
||||
|
||||
EventInstanceManager eim = player.getEventInstance();
|
||||
if (eim != null) {
|
||||
eim.playerDisconnected(player);
|
||||
}
|
||||
if (player.getMap() != null) {
|
||||
if (player.getMap() != null) {
|
||||
int mapId = player.getMapId();
|
||||
player.getMap().removePlayer(player);
|
||||
|
||||
player.getMap().removePlayer(player);
|
||||
if(GameConstants.isDojo(mapId)) {
|
||||
this.getChannelServer().freeDojoSectionIfEmpty(mapId);
|
||||
}
|
||||
@@ -842,15 +842,15 @@ public class MapleClient {
|
||||
removePlayer();
|
||||
player.saveCooldowns();
|
||||
player.saveCharToDB(true);
|
||||
|
||||
|
||||
clear();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
removePlayer();
|
||||
|
||||
final World worlda = getWorldServer();
|
||||
try {
|
||||
try {
|
||||
if (!cashshop) {
|
||||
if (!this.serverTransition) { // meaning not changing channels
|
||||
if (messengerid > 0) {
|
||||
@@ -861,7 +861,7 @@ public class MapleClient {
|
||||
final MapleFamily family = worlda.getFamily(fid);
|
||||
family.
|
||||
}
|
||||
*/
|
||||
*/
|
||||
for (MapleQuestStatus status : player.getStartedQuests()) { //This is for those quests that you have to stay logged in for a certain amount of time
|
||||
MapleQuest quest = status.getQuest();
|
||||
if (quest.getTimeLimit() > 0) {
|
||||
@@ -870,7 +870,7 @@ public class MapleClient {
|
||||
player.updateQuest(newStatus);
|
||||
}
|
||||
}
|
||||
if (guild != null) {
|
||||
if (guild != null) {
|
||||
final Server server = Server.getInstance();
|
||||
server.setGuildMemberOnline(player, false, player.getClient().getChannel());
|
||||
player.getClient().announce(MaplePacketCreator.showGuildInfo(player));
|
||||
@@ -890,7 +890,7 @@ public class MapleClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bl != null) {
|
||||
if (bl != null) {
|
||||
worlda.loggedOff(player.getName(), player.getId(), channel, player.getBuddylist().getBuddyIds());
|
||||
}
|
||||
}
|
||||
@@ -910,7 +910,7 @@ public class MapleClient {
|
||||
worlda.updateParty(party.getId(), PartyOperation.CHANGE_LEADER, lchr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bl != null) {
|
||||
worlda.loggedOff(player.getName(), player.getId(), channel, player.getBuddylist().getBuddyIds());
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
|
||||
public final class MonsterBook {
|
||||
private static final Semaphore semaphore = new Semaphore(10);
|
||||
|
||||
@@ -1768,8 +1768,12 @@ public class Commands {
|
||||
}
|
||||
newMap.respawn();
|
||||
break;
|
||||
|
||||
case "reloadshops":
|
||||
MapleShopFactory.getInstance().reloadShops();
|
||||
break;
|
||||
|
||||
case "hpmp":
|
||||
case "hpmp":
|
||||
victim = player;
|
||||
int statUpdate = 1;
|
||||
|
||||
@@ -2611,9 +2615,9 @@ public class Commands {
|
||||
player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition());
|
||||
break;
|
||||
|
||||
case "pnpcremove":
|
||||
case "playernpcremove":
|
||||
if (sub.length < 2) {
|
||||
player.yellowMessage("Syntax: !pnpcremove <playername>");
|
||||
player.yellowMessage("Syntax: !playernpcremove <playername>");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2654,7 +2658,7 @@ public class Commands {
|
||||
case "debugpacket":
|
||||
player.getMap().broadcastMessage(MaplePacketCreator.customPacket(joinStringFrom(sub, 1)));
|
||||
break;
|
||||
|
||||
|
||||
case "debugportal":
|
||||
MaplePortal portal = player.getMap().findClosestPortal(player.getPosition());
|
||||
if(portal != null) player.dropMessage(6, "Closest portal: " + portal.getId() + " '" + portal.getName() + "' Type: " + portal.getType() + " --> toMap: " + portal.getTargetMapId() + " scriptname: '" + portal.getScriptName() + "' state: " + portal.getPortalState() + ".");
|
||||
@@ -2731,6 +2735,10 @@ public class Commands {
|
||||
c.getChannelServer().debugMarriageStatus();
|
||||
break;
|
||||
|
||||
case "showpackets":
|
||||
ServerConstants.USE_DEBUG_SHOW_RCVD_PACKET = !ServerConstants.USE_DEBUG_SHOW_RCVD_PACKET;
|
||||
break;
|
||||
|
||||
case "set":
|
||||
for(int i = 0; i < sub.length - 1; i++) {
|
||||
ServerConstants.DEBUG_VALUES[i] = Integer.parseInt(sub[i + 1]);
|
||||
|
||||
@@ -28,10 +28,10 @@ import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
import tools.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
|
||||
import tools.Pair;
|
||||
import client.MapleCharacter;
|
||||
@@ -41,19 +41,19 @@ import constants.ItemConstants;
|
||||
import server.MapleItemInformationProvider;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import tools.FilePrinter;
|
||||
import tools.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze, Ronan
|
||||
*/
|
||||
public class MapleInventory implements Iterable<Item> {
|
||||
private MapleCharacter owner;
|
||||
private Map<Short, Item> inventory = new LinkedHashMap<>();
|
||||
private byte slotLimit;
|
||||
private MapleInventoryType type;
|
||||
private boolean checked = false;
|
||||
private Lock lock = new MonitoredReentrantLock(MonitoredLockType.INVENTORY, true);
|
||||
protected MapleCharacter owner;
|
||||
protected Map<Short, Item> inventory = new LinkedHashMap<>();
|
||||
protected byte slotLimit;
|
||||
protected MapleInventoryType type;
|
||||
protected boolean checked = false;
|
||||
protected Lock lock = new MonitoredReentrantLock(MonitoredLockType.INVENTORY, true);
|
||||
|
||||
public MapleInventory(MapleCharacter mc, MapleInventoryType type, byte slotLimit) {
|
||||
this.owner = mc;
|
||||
@@ -301,7 +301,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
}
|
||||
|
||||
private short addSlot(Item item) {
|
||||
protected short addSlot(Item item) {
|
||||
if(item == null) {
|
||||
return -1;
|
||||
}
|
||||
@@ -324,7 +324,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
}
|
||||
|
||||
private void addSlotFromDB(short slot, Item item) {
|
||||
protected void addSlotFromDB(short slot, Item item) {
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.put(slot, item);
|
||||
@@ -418,18 +418,22 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public static boolean checkSpot(MapleCharacter chr, Item item) {
|
||||
if (chr.getInventory(item.getInventoryType()).isFull()) return false;
|
||||
return true;
|
||||
return !chr.getInventory(item.getInventoryType()).isFull();
|
||||
}
|
||||
|
||||
public static boolean checkSpots(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items) {
|
||||
List<Integer> zeroedList = new ArrayList<>(5);
|
||||
for(byte i = 0; i < 5; i++) zeroedList.add(0);
|
||||
|
||||
return checkSpots(chr, items, zeroedList);
|
||||
return checkSpots(chr, items, false);
|
||||
}
|
||||
|
||||
public static boolean checkSpots(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, List<Integer> typesSlotsUsed) {
|
||||
public static boolean checkSpots(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, boolean useProofInv) {
|
||||
int invTypesSize = MapleInventoryType.values().length;
|
||||
List<Integer> zeroedList = new ArrayList<>(invTypesSize);
|
||||
for(byte i = 0; i < invTypesSize; i++) zeroedList.add(0);
|
||||
|
||||
return checkSpots(chr, items, zeroedList, useProofInv);
|
||||
}
|
||||
|
||||
public static boolean checkSpots(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, List<Integer> typesSlotsUsed, boolean useProofInv) {
|
||||
// assumption: no "UNDEFINED" or "EQUIPPED" items shall be tested here, all counts are >= 0.
|
||||
|
||||
Map<Integer, Short> rcvItems = new LinkedHashMap<>();
|
||||
@@ -452,7 +456,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
int itemType = rcvTypes.get(it.getKey()) - 1;
|
||||
int usedSlots = typesSlotsUsed.get(itemType);
|
||||
|
||||
int result = MapleInventoryManipulator.checkSpaceProgressively(c, it.getKey(), it.getValue(), "", usedSlots);
|
||||
int result = MapleInventoryManipulator.checkSpaceProgressively(c, it.getKey(), it.getValue(), "", usedSlots, useProofInv);
|
||||
boolean hasSpace = ((result % 2) != 0);
|
||||
|
||||
if(!hasSpace) return false;
|
||||
@@ -481,13 +485,17 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items) {
|
||||
return checkSpotsAndOwnership(chr, items, false);
|
||||
}
|
||||
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, boolean useProofInv) {
|
||||
List<Integer> zeroedList = new ArrayList<>(5);
|
||||
for(byte i = 0; i < 5; i++) zeroedList.add(0);
|
||||
|
||||
return checkSpotsAndOwnership(chr, items, zeroedList);
|
||||
return checkSpotsAndOwnership(chr, items, zeroedList, useProofInv);
|
||||
}
|
||||
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, List<Integer> typesSlotsUsed) {
|
||||
public static boolean checkSpotsAndOwnership(MapleCharacter chr, List<Pair<Item, MapleInventoryType>> items, List<Integer> typesSlotsUsed, boolean useProofInv) {
|
||||
//assumption: no "UNDEFINED" or "EQUIPPED" items shall be tested here, all counts are >= 0 and item list to be checked is a legal one.
|
||||
|
||||
Map<Long, Short> rcvItems = new LinkedHashMap<>();
|
||||
@@ -516,7 +524,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
|
||||
//System.out.print("inserting " + itemId.intValue() + " with type " + itemType + " qty " + it.getValue() + " owner '" + rcvOwners.get(it.getKey()) + "' current usedSlots:");
|
||||
//for(Integer i : typesSlotsUsed) System.out.print(" " + i);
|
||||
int result = MapleInventoryManipulator.checkSpaceProgressively(c, itemId.intValue(), it.getValue(), rcvOwners.get(it.getKey()), usedSlots);
|
||||
int result = MapleInventoryManipulator.checkSpaceProgressively(c, itemId.intValue(), it.getValue(), rcvOwners.get(it.getKey()), usedSlots, useProofInv);
|
||||
boolean hasSpace = ((result % 2) != 0);
|
||||
//System.out.print(" -> hasSpace: " + hasSpace + " RESULT : " + result + "\n");
|
||||
|
||||
|
||||
99
src/client/inventory/MapleInventoryProof.java
Normal file
99
src/client/inventory/MapleInventoryProof.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft 2016 - 2018 RonanLana
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package client.inventory;
|
||||
|
||||
import client.MapleCharacter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MapleInventoryProof extends MapleInventory {
|
||||
|
||||
public MapleInventoryProof(MapleCharacter mc) {
|
||||
super(mc, MapleInventoryType.CANHOLD, (byte) 0);
|
||||
}
|
||||
|
||||
public void cloneContents(MapleInventory inv) {
|
||||
inv.lockInventory();
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.clear();
|
||||
this.setSlotLimit(inv.getSlotLimit());
|
||||
|
||||
for(Item it : inv.list()) {
|
||||
Item item = new Item(it.getItemId(), it.getPosition(), it.getQuantity());
|
||||
inventory.put(item.getPosition(), item);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
inv.unlockInventory();
|
||||
}
|
||||
}
|
||||
|
||||
public void flushContents() {
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short addSlot(Item item) {
|
||||
if(item == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
short slotId = getNextFreeSlot();
|
||||
if (slotId < 0) {
|
||||
return -1;
|
||||
}
|
||||
inventory.put(slotId, item);
|
||||
|
||||
return slotId;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSlotFromDB(short slot, Item item) {
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.put(slot, item);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSlot(short slot) {
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.remove(slot);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ public enum MapleInventoryType {
|
||||
SETUP(3),
|
||||
ETC(4),
|
||||
CASH(5),
|
||||
CANHOLD(6), //Proof-guard for inserting after removal checks
|
||||
EQUIPPED(-1); //Seems nexon screwed something when removing an item T_T
|
||||
final byte type;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import server.movement.LifeMovementFragment;
|
||||
import client.MapleCharacter;
|
||||
import java.sql.Connection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -273,13 +274,8 @@ public class MaplePet extends Item {
|
||||
this.summoned = yes;
|
||||
}
|
||||
|
||||
public boolean canConsume(int itemId) {
|
||||
for (int petId : MapleItemInformationProvider.getInstance().petsCanConsume(itemId)) {
|
||||
if (petId == this.getItemId()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public Pair<Integer, Boolean> canConsume(int itemId) {
|
||||
return MapleItemInformationProvider.getInstance().canPetConsume(this.getItemId(), itemId);
|
||||
}
|
||||
|
||||
public void updatePosition(List<LifeMovementFragment> movement) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
package client.inventory.manipulator;
|
||||
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
@@ -38,6 +39,7 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.maps.MapleMap;
|
||||
import tools.FilePrinter;
|
||||
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -45,6 +47,7 @@ import tools.MaplePacketCreator;
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
* @author Ronan (improved check space feature & removed redundant object calls)
|
||||
*/
|
||||
public class MapleInventoryManipulator {
|
||||
|
||||
@@ -67,9 +70,11 @@ public class MapleInventoryManipulator {
|
||||
public static boolean addById(MapleClient c, int itemId, short quantity, String owner, int petid, byte flag, long expiration) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ItemConstants.getInventoryType(itemId);
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory inv = chr.getInventory(type);
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, itemId);
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(itemId);
|
||||
List<Item> existing = inv.listById(itemId);
|
||||
if (!ItemConstants.isRechargeable(itemId) && petid == -1) {
|
||||
if (existing.size() > 0) { // first update all existing slots to slotMax
|
||||
Iterator<Item> i = existing.iterator();
|
||||
@@ -97,7 +102,7 @@ public class MapleInventoryManipulator {
|
||||
Item nItem = new Item(itemId, (short) 0, newQ, petid);
|
||||
nItem.setFlag(flag);
|
||||
nItem.setExpiration(expiration);
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
short newSlot = inv.addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
@@ -107,7 +112,7 @@ public class MapleInventoryManipulator {
|
||||
nItem.setOwner(owner);
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(sandboxItem) c.getPlayer().setHasSandboxItem();
|
||||
if(sandboxItem) chr.setHasSandboxItem();
|
||||
if ((ItemConstants.isRechargeable(itemId)) && quantity == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -120,14 +125,14 @@ public class MapleInventoryManipulator {
|
||||
Item nItem = new Item(itemId, (short) 0, quantity, petid);
|
||||
nItem.setFlag(flag);
|
||||
nItem.setExpiration(expiration);
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
short newSlot = inv.addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) chr.setHasSandboxItem();
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
Item nEquip = ii.getEquipById(itemId);
|
||||
@@ -136,14 +141,14 @@ public class MapleInventoryManipulator {
|
||||
if (owner != null) {
|
||||
nEquip.setOwner(owner);
|
||||
}
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nEquip);
|
||||
short newSlot = inv.addItem(nEquip);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nEquip))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nEquip)) c.getPlayer().setHasSandboxItem();
|
||||
if(MapleInventoryManipulator.isSandboxItem(nEquip)) chr.setHasSandboxItem();
|
||||
} else {
|
||||
throw new RuntimeException("Trying to create equip with non-one quantity");
|
||||
}
|
||||
@@ -159,17 +164,19 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
public static boolean addFromDrop(MapleClient c, Item item, boolean show, int petId) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = item.getInventoryType();
|
||||
if (ii.isPickupRestricted(item.getItemId()) && c.getPlayer().haveItemWithId(item.getItemId(), true)) {
|
||||
if (ii.isPickupRestricted(item.getItemId()) && chr.haveItemWithId(item.getItemId(), true)) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.showItemUnavailable());
|
||||
return false;
|
||||
}
|
||||
short quantity = item.getQuantity();
|
||||
MapleInventory inv = chr.getInventory(type);
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(item.getItemId());
|
||||
List<Item> existing = inv.listById(item.getItemId());
|
||||
if (!ItemConstants.isRechargeable(item.getItemId()) && petId == -1) {
|
||||
if (existing.size() > 0) { // first update all existing slots to slotMax
|
||||
Iterator<Item> i = existing.iterator();
|
||||
@@ -195,7 +202,7 @@ public class MapleInventoryManipulator {
|
||||
nItem.setExpiration(item.getExpiration());
|
||||
nItem.setOwner(item.getOwner());
|
||||
nItem.setFlag(item.getFlag());
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
short newSlot = inv.addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
@@ -203,32 +210,32 @@ public class MapleInventoryManipulator {
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) chr.setHasSandboxItem();
|
||||
}
|
||||
} else {
|
||||
Item nItem = new Item(item.getItemId(), (short) 0, quantity, petId);
|
||||
nItem.setExpiration(item.getExpiration());
|
||||
nItem.setFlag(item.getFlag());
|
||||
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(nItem);
|
||||
short newSlot = inv.addItem(nItem);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, nItem))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) c.getPlayer().setHasSandboxItem();
|
||||
if(MapleInventoryManipulator.isSandboxItem(nItem)) chr.setHasSandboxItem();
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
} else if (quantity == 1) {
|
||||
short newSlot = c.getPlayer().getInventory(type).addItem(item);
|
||||
short newSlot = inv.addItem(item);
|
||||
if (newSlot == -1) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return false;
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(0, item))));
|
||||
if(MapleInventoryManipulator.isSandboxItem(item)) c.getPlayer().setHasSandboxItem();
|
||||
if(MapleInventoryManipulator.isSandboxItem(item)) chr.setHasSandboxItem();
|
||||
} else {
|
||||
FilePrinter.printError(FilePrinter.ITEM, "Tried to pickup Equip id " + item.getItemId() + " containing more than 1 quantity --> " + quantity);
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
@@ -248,14 +255,16 @@ public class MapleInventoryManipulator {
|
||||
public static boolean checkSpace(MapleClient c, int itemid, int quantity, String owner) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory inv = chr.getInventory(type);
|
||||
|
||||
if(ii.isPickupRestricted(itemid) && haveItemWithId(c.getPlayer().getInventory(type), itemid)) {
|
||||
if(ii.isPickupRestricted(itemid) && haveItemWithId(inv, itemid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, itemid);
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(itemid);
|
||||
List<Item> existing = inv.listById(itemid);
|
||||
if (!ItemConstants.isRechargeable(itemid)) {
|
||||
if (existing.size() > 0) // first update all existing slots to slotMax
|
||||
{
|
||||
@@ -279,13 +288,13 @@ public class MapleInventoryManipulator {
|
||||
} else {
|
||||
numSlotsNeeded = 1;
|
||||
}
|
||||
return !c.getPlayer().getInventory(type).isFull(numSlotsNeeded - 1);
|
||||
return !inv.isFull(numSlotsNeeded - 1);
|
||||
} else {
|
||||
return !c.getPlayer().getInventory(type).isFull();
|
||||
return !inv.isFull();
|
||||
}
|
||||
}
|
||||
|
||||
public static int checkSpaceProgressively(MapleClient c, int itemid, int quantity, String owner, int usedSlots) {
|
||||
public static int checkSpaceProgressively(MapleClient c, int itemid, int quantity, String owner, int usedSlots, boolean useProofInv) {
|
||||
// return value --> bit0: if has space for this one;
|
||||
// value after: new slots filled;
|
||||
// assumption: equipments always have slotMax == 1.
|
||||
@@ -293,16 +302,18 @@ public class MapleInventoryManipulator {
|
||||
int returnValue;
|
||||
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
|
||||
MapleInventoryType type = !useProofInv ? ItemConstants.getInventoryType(itemid) : MapleInventoryType.CANHOLD;
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory inv = chr.getInventory(type);
|
||||
|
||||
if(ii.isPickupRestricted(itemid) && haveItemWithId(c.getPlayer().getInventory(type), itemid)) {
|
||||
if(ii.isPickupRestricted(itemid) && haveItemWithId(inv, itemid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!type.equals(MapleInventoryType.EQUIP)) {
|
||||
short slotMax = ii.getSlotMax(c, itemid);
|
||||
if (!ItemConstants.isRechargeable(itemid)) {
|
||||
List<Item> existing = c.getPlayer().getInventory(type).listById(itemid);
|
||||
List<Item> existing = inv.listById(itemid);
|
||||
|
||||
if (existing.size() > 0) // first update all existing slots to slotMax
|
||||
{
|
||||
@@ -328,11 +339,11 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
returnValue = ((numSlotsNeeded + usedSlots) << 1);
|
||||
returnValue += (numSlotsNeeded == 0 || !c.getPlayer().getInventory(type).isFullAfterSomeItems(numSlotsNeeded - 1, usedSlots)) ? 1 : 0;
|
||||
returnValue += (numSlotsNeeded == 0 || !inv.isFullAfterSomeItems(numSlotsNeeded - 1, usedSlots)) ? 1 : 0;
|
||||
//System.out.print(" needed " + numSlotsNeeded + " used " + usedSlots + " rval " + returnValue);
|
||||
} else {
|
||||
returnValue = ((quantity + usedSlots) << 1);
|
||||
returnValue += (!c.getPlayer().getInventory(type).isFullAfterSomeItems(0, usedSlots)) ? 1 : 0;
|
||||
returnValue += (!inv.isFullAfterSomeItems(0, usedSlots)) ? 1 : 0;
|
||||
//System.out.print(" eqpneeded " + 1 + " used " + usedSlots + " rval " + returnValue);
|
||||
}
|
||||
|
||||
@@ -344,9 +355,30 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
public static void removeFromSlot(MapleClient c, MapleInventoryType type, short slot, short quantity, boolean fromDrop, boolean consume) {
|
||||
Item item = c.getPlayer().getInventory(type).getItem(slot);
|
||||
MapleInventory inv = c.getPlayer().getInventory(type);
|
||||
Item item = inv.getItem(slot);
|
||||
boolean allowZero = consume && ItemConstants.isRechargeable(item.getItemId());
|
||||
c.getPlayer().getInventory(type).removeItem(slot, quantity, allowZero);
|
||||
|
||||
if(type == MapleInventoryType.EQUIPPED) {
|
||||
inv.lockInventory();
|
||||
try {
|
||||
c.getPlayer().unequippedItem((Equip) item);
|
||||
inv.removeItem(slot, quantity, allowZero);
|
||||
} finally {
|
||||
inv.unlockInventory();
|
||||
}
|
||||
|
||||
announceModifyInventory(c, item, fromDrop, allowZero);
|
||||
} else {
|
||||
inv.removeItem(slot, quantity, allowZero);
|
||||
|
||||
if(type != MapleInventoryType.CANHOLD) {
|
||||
announceModifyInventory(c, item, fromDrop, allowZero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void announceModifyInventory(MapleClient c, Item item, boolean fromDrop, boolean allowZero) {
|
||||
if (item.getQuantity() == 0 && !allowZero) {
|
||||
c.announce(MaplePacketCreator.modifyInventory(fromDrop, Collections.singletonList(new ModifyInventory(3, item))));
|
||||
} else {
|
||||
@@ -374,7 +406,7 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeQuantity > 0) {
|
||||
if (removeQuantity > 0 && type != MapleInventoryType.CANHOLD) {
|
||||
throw new RuntimeException("[HACK] Not enough items available of Item:" + itemId + ", Quantity (After Quantity/Over Current Quantity): " + (quantity - removeQuantity) + "/" + quantity);
|
||||
}
|
||||
}
|
||||
@@ -384,15 +416,17 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
public static void move(MapleClient c, MapleInventoryType type, short src, short dst) {
|
||||
MapleInventory inv = c.getPlayer().getInventory(type);
|
||||
|
||||
if (src < 0 || dst < 0) {
|
||||
return;
|
||||
}
|
||||
if(dst > c.getPlayer().getInventory(type).getSlotLimit()) {
|
||||
if(dst > inv.getSlotLimit()) {
|
||||
return;
|
||||
}
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
Item source = c.getPlayer().getInventory(type).getItem(src);
|
||||
Item initialTarget = c.getPlayer().getInventory(type).getItem(dst);
|
||||
Item source = inv.getItem(src);
|
||||
Item initialTarget = inv.getItem(dst);
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
@@ -402,7 +436,7 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
short oldsrcQ = source.getQuantity();
|
||||
short slotMax = ii.getSlotMax(c, source.getItemId());
|
||||
c.getPlayer().getInventory(type).move(src, dst, slotMax);
|
||||
inv.move(src, dst, slotMax);
|
||||
final List<ModifyInventory> mods = new ArrayList<>();
|
||||
if (!(type.equals(MapleInventoryType.EQUIP) || type.equals(MapleInventoryType.CASH)) && initialTarget != null && initialTarget.getItemId() == source.getItemId() && !ItemConstants.isRechargeable(source.getItemId()) && isSameOwner(source, initialTarget)) {
|
||||
if ((olddstQ + oldsrcQ) > slotMax) {
|
||||
@@ -419,76 +453,83 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
public static void equip(MapleClient c, short src, short dst) {
|
||||
Equip source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(src);
|
||||
if (source == null || !MapleItemInformationProvider.getInstance().canWearEquipment(c.getPlayer(), source, dst)) {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory eqpInv = chr.getInventory(MapleInventoryType.EQUIP);
|
||||
MapleInventory eqpdInv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
|
||||
Equip source = (Equip) eqpInv.getItem(src);
|
||||
if (source == null || !ii.canWearEquipment(chr, source, dst)) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
} else if ((((source.getItemId() >= 1902000 && source.getItemId() <= 1902002) || source.getItemId() == 1912000) && c.getPlayer().isCygnus()) || ((source.getItemId() >= 1902005 && source.getItemId() <= 1902007) || source.getItemId() == 1912005) && !c.getPlayer().isCygnus()) {// Adventurer taming equipment
|
||||
} else if ((((source.getItemId() >= 1902000 && source.getItemId() <= 1902002) || source.getItemId() == 1912000) && chr.isCygnus()) || ((source.getItemId() >= 1902005 && source.getItemId() <= 1902007) || source.getItemId() == 1912005) && !chr.isCygnus()) {// Adventurer taming equipment
|
||||
return;
|
||||
}
|
||||
boolean itemChanged = false;
|
||||
if (MapleItemInformationProvider.getInstance().isUntradeableOnEquip(source.getItemId())) {
|
||||
if (ii.isUntradeableOnEquip(source.getItemId())) {
|
||||
source.setFlag((byte) ItemConstants.UNTRADEABLE);
|
||||
itemChanged = true;
|
||||
}
|
||||
if (source.getRingId() > -1) {
|
||||
c.getPlayer().getRingById(source.getRingId()).equip();
|
||||
}
|
||||
if (dst == -6) { // unequip the overall
|
||||
Item top = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -5);
|
||||
Item top = eqpdInv.getItem((short) -5);
|
||||
if (top != null && ItemConstants.isOverall(top.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
if (eqpInv.isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -5, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
unequip(c, (byte) -5, eqpInv.getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -5) {
|
||||
final Item bottom = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -6);
|
||||
final Item bottom = eqpdInv.getItem((short) -6);
|
||||
if (bottom != null && ItemConstants.isOverall(source.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
if (eqpInv.isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -6, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
unequip(c, (byte) -6, eqpInv.getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -10) {// check if weapon is two-handed
|
||||
Item weapon = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -11);
|
||||
if (weapon != null && MapleItemInformationProvider.getInstance().isTwoHanded(weapon.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
Item weapon = eqpdInv.getItem((short) -11);
|
||||
if (weapon != null && ii.isTwoHanded(weapon.getItemId())) {
|
||||
if (eqpInv.isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -11, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
unequip(c, (byte) -11, eqpInv.getNextFreeSlot());
|
||||
}
|
||||
} else if (dst == -11) {
|
||||
Item shield = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10);
|
||||
if (shield != null && MapleItemInformationProvider.getInstance().isTwoHanded(source.getItemId())) {
|
||||
if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
|
||||
Item shield = eqpdInv.getItem((short) -10);
|
||||
if (shield != null && ii.isTwoHanded(source.getItemId())) {
|
||||
if (eqpInv.isFull()) {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
c.announce(MaplePacketCreator.getShowInventoryFull());
|
||||
return;
|
||||
}
|
||||
unequip(c, (byte) -10, c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNextFreeSlot());
|
||||
unequip(c, (byte) -10, eqpInv.getNextFreeSlot());
|
||||
}
|
||||
}
|
||||
if (dst == -18) {
|
||||
if (c.getPlayer().getMount() != null) {
|
||||
c.getPlayer().getMount().setItemId(source.getItemId());
|
||||
if (chr.getMount() != null) {
|
||||
chr.getMount().setItemId(source.getItemId());
|
||||
}
|
||||
}
|
||||
if (source.getItemId() == 1122017) {
|
||||
c.getPlayer().equipPendantOfSpirit();
|
||||
}
|
||||
|
||||
//1112413, 1112414, 1112405 (Lilin's Ring)
|
||||
source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(src);
|
||||
Equip target = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeSlot(src);
|
||||
source = (Equip) eqpInv.getItem(src);
|
||||
Equip target = (Equip) eqpdInv.getItem(dst);
|
||||
eqpInv.removeSlot(src);
|
||||
if (target != null) {
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeSlot(dst);
|
||||
eqpdInv.lockInventory();
|
||||
try {
|
||||
chr.unequippedItem(target);
|
||||
eqpdInv.removeSlot(dst);
|
||||
} finally {
|
||||
eqpdInv.unlockInventory();
|
||||
}
|
||||
}
|
||||
|
||||
final List<ModifyInventory> mods = new ArrayList<>();
|
||||
@@ -498,23 +539,38 @@ public class MapleInventoryManipulator {
|
||||
}
|
||||
|
||||
source.setPosition(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addItemFromDB(source);
|
||||
|
||||
eqpdInv.lockInventory();
|
||||
try {
|
||||
if (source.getRingId() > -1) {
|
||||
chr.getRingById(source.getRingId()).equip();
|
||||
}
|
||||
chr.equippedItem(source);
|
||||
eqpdInv.addItemFromDB(source);
|
||||
} finally {
|
||||
eqpdInv.unlockInventory();
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
target.setPosition(src);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).addItemFromDB(target);
|
||||
eqpInv.addItemFromDB(target);
|
||||
}
|
||||
if (c.getPlayer().getBuffedValue(MapleBuffStat.BOOSTER) != null && ItemConstants.isWeapon(source.getItemId())) {
|
||||
c.getPlayer().cancelBuffStats(MapleBuffStat.BOOSTER);
|
||||
if (chr.getBuffedValue(MapleBuffStat.BOOSTER) != null && ItemConstants.isWeapon(source.getItemId())) {
|
||||
chr.cancelBuffStats(MapleBuffStat.BOOSTER);
|
||||
}
|
||||
|
||||
mods.add(new ModifyInventory(2, source, src));
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, mods));
|
||||
c.getPlayer().equipChanged();
|
||||
chr.equipChanged();
|
||||
}
|
||||
|
||||
public static void unequip(MapleClient c, short src, short dst) {
|
||||
Equip source = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(src);
|
||||
Equip target = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(dst);
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory eqpInv = chr.getInventory(MapleInventoryType.EQUIP);
|
||||
MapleInventory eqpdInv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
|
||||
Equip source = (Equip) eqpdInv.getItem(src);
|
||||
Equip target = (Equip) eqpInv.getItem(dst);
|
||||
if (dst < 0) {
|
||||
return;
|
||||
}
|
||||
@@ -525,24 +581,29 @@ public class MapleInventoryManipulator {
|
||||
c.announce(MaplePacketCreator.getInventoryFull());
|
||||
return;
|
||||
}
|
||||
if (source.getItemId() == 1122017) {
|
||||
c.getPlayer().unequipPendantOfSpirit();
|
||||
|
||||
eqpdInv.lockInventory();
|
||||
try {
|
||||
if (source.getRingId() > -1) {
|
||||
chr.getRingById(source.getRingId()).unequip();
|
||||
}
|
||||
chr.unequippedItem(source);
|
||||
eqpdInv.removeSlot(src);
|
||||
} finally {
|
||||
eqpdInv.unlockInventory();
|
||||
}
|
||||
if (source.getRingId() > -1) {
|
||||
c.getPlayer().getRingById(source.getRingId()).unequip();
|
||||
}
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeSlot(src);
|
||||
|
||||
if (target != null) {
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeSlot(dst);
|
||||
eqpInv.removeSlot(dst);
|
||||
}
|
||||
source.setPosition(dst);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIP).addItemFromDB(source);
|
||||
eqpInv.addItemFromDB(source);
|
||||
if (target != null) {
|
||||
target.setPosition(src);
|
||||
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).addItemFromDB(target);
|
||||
eqpdInv.addItemFromDB(target);
|
||||
}
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(2, source, src))));
|
||||
c.getPlayer().equipChanged();
|
||||
chr.equipChanged();
|
||||
}
|
||||
|
||||
public static void drop(MapleClient c, MapleInventoryType type, short src, short quantity) {
|
||||
@@ -550,30 +611,32 @@ public class MapleInventoryManipulator {
|
||||
if (src < 0) {
|
||||
type = MapleInventoryType.EQUIPPED;
|
||||
}
|
||||
Item source = c.getPlayer().getInventory(type).getItem(src);
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleInventory inv = chr.getInventory(type);
|
||||
Item source = inv.getItem(src);
|
||||
|
||||
if (c.getPlayer().getTrade() != null || c.getPlayer().getMiniGame() != null || source == null) { //Only check needed would prob be merchants (to see if the player is in one)
|
||||
if (chr.getTrade() != null || chr.getMiniGame() != null || source == null) { //Only check needed would prob be merchants (to see if the player is in one)
|
||||
return;
|
||||
}
|
||||
int itemId = source.getItemId();
|
||||
if (ItemConstants.isPet(itemId)) {
|
||||
return;
|
||||
}
|
||||
if (type == MapleInventoryType.EQUIPPED && itemId == 1122017) {
|
||||
c.getPlayer().unequipPendantOfSpirit();
|
||||
}
|
||||
if (c.getPlayer().getItemEffect() == itemId && source.getQuantity() == 1) {
|
||||
c.getPlayer().setItemEffect(0);
|
||||
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.itemEffect(c.getPlayer().getId(), 0));
|
||||
|
||||
MapleMap map = chr.getMap();
|
||||
if (chr.getItemEffect() == itemId && source.getQuantity() == 1) {
|
||||
chr.setItemEffect(0);
|
||||
map.broadcastMessage(MaplePacketCreator.itemEffect(chr.getId(), 0));
|
||||
} else if (itemId == 5370000 || itemId == 5370001) {
|
||||
if (c.getPlayer().getItemQuantity(itemId, false) == 1) {
|
||||
c.getPlayer().setChalkboard(null);
|
||||
if (chr.getItemQuantity(itemId, false) == 1) {
|
||||
chr.setChalkboard(null);
|
||||
}
|
||||
}
|
||||
if ((!ItemConstants.isRechargeable(itemId) && source.getQuantity() < quantity) || quantity < 0) {
|
||||
return;
|
||||
}
|
||||
Point dropPos = new Point(c.getPlayer().getPosition());
|
||||
Point dropPos = new Point(chr.getPosition());
|
||||
if (quantity < source.getQuantity() && !ItemConstants.isRechargeable(itemId)) {
|
||||
Item target = source.copy();
|
||||
target.setQuantity(quantity);
|
||||
@@ -582,50 +645,61 @@ public class MapleInventoryManipulator {
|
||||
|
||||
if(ItemConstants.isNewYearCardEtc(itemId)) {
|
||||
if(itemId == 4300000) {
|
||||
NewYearCardRecord.removeAllNewYearCard(true, c.getPlayer());
|
||||
NewYearCardRecord.removeAllNewYearCard(true, chr);
|
||||
c.getAbstractPlayerInteraction().removeAll(4300000);
|
||||
} else {
|
||||
NewYearCardRecord.removeAllNewYearCard(false, c.getPlayer());
|
||||
NewYearCardRecord.removeAllNewYearCard(false, chr);
|
||||
c.getAbstractPlayerInteraction().removeAll(4301000);
|
||||
}
|
||||
} else if (ItemConstants.isWeddingRing(source.getItemId())) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
} else if (c.getPlayer().getMap().getEverlast()) {
|
||||
map.disappearingItemDrop(chr, chr, target, dropPos);
|
||||
} else if (map.getEverlast()) {
|
||||
if (ii.isDropRestricted(target.getItemId()) || ii.isCash(target.getItemId()) || isDroppedItemRestricted(target)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
map.disappearingItemDrop(chr, chr, target, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, true);
|
||||
map.spawnItemDrop(chr, chr, target, dropPos, true, true);
|
||||
}
|
||||
} else if (ii.isDropRestricted(target.getItemId()) || ii.isCash(target.getItemId()) || isDroppedItemRestricted(target)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
|
||||
map.disappearingItemDrop(chr, chr, target, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos, true, true);
|
||||
map.spawnItemDrop(chr, chr, target, dropPos, true, true);
|
||||
}
|
||||
} else {
|
||||
c.getPlayer().getInventory(type).removeSlot(src);
|
||||
if (type == MapleInventoryType.EQUIPPED) {
|
||||
inv.lockInventory();
|
||||
try {
|
||||
chr.unequippedItem((Equip) source);
|
||||
inv.removeSlot(src);
|
||||
} finally {
|
||||
inv.unlockInventory();
|
||||
}
|
||||
} else {
|
||||
inv.removeSlot(src);
|
||||
}
|
||||
|
||||
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(3, source))));
|
||||
if (src < 0) {
|
||||
c.getPlayer().equipChanged();
|
||||
chr.equipChanged();
|
||||
} else if(ItemConstants.isNewYearCardEtc(itemId)) {
|
||||
if(itemId == 4300000) {
|
||||
NewYearCardRecord.removeAllNewYearCard(true, c.getPlayer());
|
||||
NewYearCardRecord.removeAllNewYearCard(true, chr);
|
||||
c.getAbstractPlayerInteraction().removeAll(4300000);
|
||||
} else {
|
||||
NewYearCardRecord.removeAllNewYearCard(false, c.getPlayer());
|
||||
NewYearCardRecord.removeAllNewYearCard(false, chr);
|
||||
c.getAbstractPlayerInteraction().removeAll(4301000);
|
||||
}
|
||||
}
|
||||
|
||||
if (c.getPlayer().getMap().getEverlast()) {
|
||||
if (map.getEverlast()) {
|
||||
if (ii.isDropRestricted(itemId) || ii.isCash(itemId) || isDroppedItemRestricted(source)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos);
|
||||
map.disappearingItemDrop(chr, chr, source, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, true);
|
||||
map.spawnItemDrop(chr, chr, source, dropPos, true, true);
|
||||
}
|
||||
} else if (ii.isDropRestricted(itemId) || ii.isCash(itemId) || isDroppedItemRestricted(source)) {
|
||||
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos);
|
||||
map.disappearingItemDrop(chr, chr, source, dropPos);
|
||||
} else {
|
||||
c.getPlayer().getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos, true, true);
|
||||
map.spawnItemDrop(chr, chr, source, dropPos, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user