Poison/slow update + Map-persistent diseases + Selling zero-qty rechs.

Rebalanced CafePQ rewards.
Rebalanced drop chance of some equipments and HT drops with high rates.
Fixed an weird issue where a "Targa hat" would appear as a debuff effect.
Added visual effect to be displayed to other players when the custom "Chair Mastery" skill is being used.
Slow disease is now visible to other players.
Poison damage now displays the correct damage amount to other players.
Disease status are now visible for other players when changing maps.
Fixed recharging price being accounted incorrectly.
Fixed zero-quantity rechargeables not being able to sell at NPC shops.
This commit is contained in:
ronancpl
2018-05-03 14:05:23 -03:00
parent 7d0f1cb311
commit 727dfb2d62
33 changed files with 590 additions and 303 deletions
+79 -37
View File
@@ -91,8 +91,8 @@ public class MapleItemInformationProvider {
protected Map<Integer, MapleStatEffect> itemEffects = new HashMap<>();
protected Map<Integer, Map<String, Integer>> equipStatsCache = new HashMap<>();
protected Map<Integer, Equip> equipCache = new HashMap<>();
protected Map<Integer, Double> priceCache = new HashMap<>();
protected Map<Integer, Integer> wholePriceCache = new HashMap<>();
protected Map<Integer, Double> unitPriceCache = new HashMap<>();
protected Map<Integer, Integer> projectileWatkCache = new HashMap<>();
protected Map<Integer, String> nameCache = new HashMap<>();
protected Map<Integer, String> descCache = new HashMap<>();
@@ -421,54 +421,96 @@ public class MapleItemInformationProvider {
return pEntry;
}
private Pair<Integer, Double> getItemPriceData(int itemId) {
MapleData item = getItemData(itemId);
if (item == null) {
wholePriceCache.put(itemId, -1);
unitPriceCache.put(itemId, 0.0);
return new Pair<>(-1, 0.0);
}
int pEntry = -1;
MapleData pData = item.getChildByPath("info/price");
if (pData != null) {
pEntry = MapleDataTool.getInt(pData);
}
double fEntry = 0.0f;
pData = item.getChildByPath("info/unitPrice");
if (pData != null) {
try {
fEntry = MapleDataTool.getDouble(pData);
} catch (Exception e) {
fEntry = (double) MapleDataTool.getInt(pData);
}
}
wholePriceCache.put(itemId, pEntry);
unitPriceCache.put(itemId, fEntry);
return new Pair<>(pEntry, fEntry);
}
public int getWholePrice(int itemId) {
if (wholePriceCache.containsKey(itemId)) {
return wholePriceCache.get(itemId);
}
MapleData item = getItemData(itemId);
if (item == null) {
return -1;
return getItemPriceData(itemId).getLeft();
}
public double getUnitPrice(int itemId) {
if (unitPriceCache.containsKey(itemId)) {
return unitPriceCache.get(itemId);
}
int pEntry;
MapleData pData = item.getChildByPath("info/price");
if (pData == null) {
return -1;
}
pEntry = MapleDataTool.getInt(pData);
wholePriceCache.put(itemId, pEntry);
return pEntry;
return getItemPriceData(itemId).getRight();
}
public double getPrice(int itemId) {
if (priceCache.containsKey(itemId)) {
return priceCache.get(itemId);
}
MapleData item = getItemData(itemId);
if (item == null) {
public int getPrice(int itemId, int quantity) {
int retPrice = getWholePrice(itemId);
if(retPrice == -1) {
return -1;
}
double pEntry;
MapleData pData = item.getChildByPath("info/unitPrice");
if (pData != null) {
try {
pEntry = MapleDataTool.getDouble(pData);
} catch (Exception e) {
pEntry = (double) MapleDataTool.getInt(pData);
}
if(!ItemConstants.isRechargable(itemId)) {
retPrice *= quantity;
} else {
pData = item.getChildByPath("info/price");
if (pData == null) {
return -1;
}
try {
pEntry = (double) MapleDataTool.getInt(pData);
} catch(Exception e) {
priceCache.put(itemId, 0.0);
return 0;
retPrice += Math.ceil(quantity * getUnitPrice(itemId));
}
return retPrice;
}
public static boolean canSell(Item item, short quantity) {
if (item == null) { //Basic check
return false;
}
short iQuant = item.getQuantity();
if (iQuant == 0xFFFF) {
iQuant = 1;
} else if(iQuant < 0) {
return false;
}
if (!ItemConstants.isRechargable(item.getItemId())) {
if (iQuant == 0 || quantity > iQuant) {
return false;
}
}
priceCache.put(itemId, pEntry);
return pEntry;
return true;
}
public static short getSellingQuantity(Item item, short quantity) {
if (ItemConstants.isRechargable(item.getItemId())) {
quantity = item.getQuantity();
if (quantity == 0xFFFF) {
quantity = 1;
}
}
return quantity;
}
protected String getEquipmentSlot(int itemId) {
+46 -59
View File
@@ -88,7 +88,7 @@ public class MapleShop {
return;
}
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
if (item != null && item.getPrice() > 0) {
if (item.getPrice() > 0) {
if (c.getPlayer().getMeso() >= (long) item.getPrice() * quantity) {
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (!ItemConstants.isRechargable(itemId)) { //Pets can't be bought from shops
@@ -107,77 +107,64 @@ public class MapleShop {
} else
c.announce(MaplePacketCreator.shopTransaction((byte) 2));
} else if (item != null && item.getPitch() > 0) {
if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= (long) item.getPitch() * quantity) {
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (!ItemConstants.isRechargable(itemId)) {
MapleInventoryManipulator.addById(c, itemId, quantity);
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
} else {
short slotMax = ii.getSlotMax(c, item.getItemId());
quantity = slotMax;
MapleInventoryManipulator.addById(c, itemId, quantity);
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
}
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
} else
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
}
} else if (c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token) != 0) {
int amount = c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token);
int value = amount * tokenvalue;
int cost = item.getPrice() * quantity;
if (c.getPlayer().getMeso() + value >= cost) {
int cardreduce = value - cost;
int diff = cardreduce + c.getPlayer().getMeso();
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (ItemConstants.isPet(itemId)) {
int petid = MaplePet.createPet(itemId);
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
} else {
MapleInventoryManipulator.addById(c, itemId, quantity);
}
c.getPlayer().gainMeso(diff, false);
} else if (item.getPitch() > 0) {
if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= (long) item.getPitch() * quantity) {
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (!ItemConstants.isRechargable(itemId)) {
MapleInventoryManipulator.addById(c, itemId, quantity);
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
} else {
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
short slotMax = ii.getSlotMax(c, item.getItemId());
quantity = slotMax;
MapleInventoryManipulator.addById(c, itemId, quantity);
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false);
}
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
} else
c.announce(MaplePacketCreator.shopTransaction((byte) 2));
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
}
} else if (c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token) != 0) {
int amount = c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token);
int value = amount * tokenvalue;
int cost = item.getPrice() * quantity;
if (c.getPlayer().getMeso() + value >= cost) {
int cardreduce = value - cost;
int diff = cardreduce + c.getPlayer().getMeso();
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (ItemConstants.isPet(itemId)) {
int petid = MaplePet.createPet(itemId);
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
} else {
MapleInventoryManipulator.addById(c, itemId, quantity);
}
c.getPlayer().gainMeso(diff, false);
} else {
c.announce(MaplePacketCreator.shopTransaction((byte) 3));
}
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
} else {
c.announce(MaplePacketCreator.shopTransaction((byte) 2));
}
}
}
public void sell(MapleClient c, MapleInventoryType type, short slot, short quantity) {
if (quantity == 0xFFFF || quantity == 0) {
quantity = 1;
}
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
Item item = c.getPlayer().getInventory(type).getItem((short) slot);
if (item == null){ //Basic check
return;
}
if (ItemConstants.isRechargable(item.getItemId())) {
quantity = item.getQuantity();
}
if (quantity < 0) {
} else if (quantity < 0) {
return;
}
short iQuant = item.getQuantity();
if (iQuant == 0xFFFF) {
iQuant = 1;
}
if (quantity <= iQuant && iQuant > 0) {
Item item = c.getPlayer().getInventory(type).getItem((short) slot);
if(MapleItemInformationProvider.canSell(item, quantity)) {
quantity = MapleItemInformationProvider.getSellingQuantity(item, quantity);
MapleInventoryManipulator.removeFromSlot(c, type, (byte) slot, quantity, false);
double price;
if (ItemConstants.isRechargable(item.getItemId())) {
price = ii.getWholePrice(item.getItemId()) / (double) ii.getSlotMax(c, item.getItemId());
} else {
price = ii.getPrice(item.getItemId());
}
int recvMesos = (int) Math.max(Math.ceil(price * quantity), 0);
if (price != -1 && recvMesos > 0) {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
int recvMesos = ii.getPrice(item.getItemId(), quantity);
if (recvMesos > 0) {
c.getPlayer().gainMeso(recvMesos, false);
}
c.announce(MaplePacketCreator.shopTransaction((byte) 0x8));
@@ -195,7 +182,7 @@ public class MapleShop {
return;
}
if (item.getQuantity() < slotMax) {
int price = (int) Math.round(ii.getPrice(item.getItemId()) * (slotMax - item.getQuantity()));
int price = (int) Math.ceil(ii.getUnitPrice(item.getItemId()) * (slotMax - item.getQuantity()));
if (c.getPlayer().getMeso() >= price) {
item.setQuantity(slotMax);
c.getPlayer().forceUpdateItem(item);
+1 -1
View File
@@ -552,7 +552,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
for (Integer chrid : attackerChrids) {
MapleCharacter chr = mapChars.get(chrid);
if(chr != null && chr.isLoggedin() && !chr.isAwayFromWorld()) {
if(chr != null && chr.isLoggedinWorld()) {
chr.updateQuestMobCount(mobid);
}
}
+1 -1
View File
@@ -238,7 +238,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
String qtyStr = (item.getQuantity() > 1) ? " (qty. " + item.getQuantity() + ")" : "";
MapleCharacter player = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
if(player != null && player.isLoggedin() && !player.isAwayFromWorld()) {
if(player != null && player.isLoggedinWorld()) {
player.dropMessage(6, "[HIRED MERCHANT] Item '" + MapleItemInformationProvider.getInstance().getName(item.getItemId()) + "'" + qtyStr + " has been sold for " + mesos + " mesos.");
}
}
+5
View File
@@ -2322,6 +2322,11 @@ public class MapleMap {
}
chr.receivePartyMemberHP();
announcePlayerDiseases(chr.getClient());
}
private static void announcePlayerDiseases(final MapleClient c) {
Server.getInstance().registerAnnouncePlayerDiseases(c);
}
public MaplePortal getRandomPlayerSpawnpoint() {
+1 -3
View File
@@ -1,5 +1,3 @@
package server.maps;
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
@@ -21,7 +19,7 @@ package server.maps;
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 server.maps;
/**
*