New Year cards + Info on PlayerShops/HiredMerchants

New Year is coming soon! Figured out implementation for the New Year cards. Opcodes and packet structures are thanks to Eric.
New Year effect crashes/dc's the player in some cases.
Added informative notes to shop owners when transactioning an item/bundle.
This commit is contained in:
ronancpl
2017-12-19 16:40:45 -02:00
parent c1126213cc
commit 012f965f6a
19 changed files with 799 additions and 56 deletions
+22 -1
View File
@@ -28,6 +28,7 @@ import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.ModifyInventory;
import client.newyear.NewYearCardRecord;
import constants.ItemConstants;
import constants.ServerConstants;
@@ -544,7 +545,7 @@ public class MapleInventoryManipulator {
c.getPlayer().setChalkboard(null);
}
}
if (source == null || (!ItemConstants.isRechargable(itemId) && source.getQuantity() < quantity) || quantity < 0) {
if ((!ItemConstants.isRechargable(itemId) && source.getQuantity() < quantity) || quantity < 0) {
return;
}
Point dropPos = new Point(c.getPlayer().getPosition());
@@ -553,6 +554,17 @@ public class MapleInventoryManipulator {
target.setQuantity(quantity);
source.setQuantity((short) (source.getQuantity() - quantity));
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(1, source))));
if(ItemConstants.isNewYearCardEtc(itemId)) {
if(itemId == 4300000) {
NewYearCardRecord.removeAllNewYearCard(true, c.getPlayer());
c.getAbstractPlayerInteraction().removeAll(4300000);
} else {
NewYearCardRecord.removeAllNewYearCard(false, c.getPlayer());
c.getAbstractPlayerInteraction().removeAll(4301000);
}
}
boolean weddingRing = source.getItemId() == 1112803 || source.getItemId() == 1112806 || source.getItemId() == 1112807 || source.getItemId() == 1112809;
if (weddingRing) {
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), target, dropPos);
@@ -572,7 +584,16 @@ public class MapleInventoryManipulator {
c.announce(MaplePacketCreator.modifyInventory(true, Collections.singletonList(new ModifyInventory(3, source))));
if (src < 0) {
c.getPlayer().equipChanged();
} else if(ItemConstants.isNewYearCardEtc(itemId)) {
if(itemId == 4300000) {
NewYearCardRecord.removeAllNewYearCard(true, c.getPlayer());
c.getAbstractPlayerInteraction().removeAll(4300000);
} else {
NewYearCardRecord.removeAllNewYearCard(false, c.getPlayer());
c.getAbstractPlayerInteraction().removeAll(4301000);
}
}
if (c.getPlayer().getMap().getEverlast()) {
if (ii.isDropRestricted(itemId) || ii.isCash(itemId) || isDroppedItemRestricted(source)) {
c.getPlayer().getMap().disappearingItemDrop(c.getPlayer(), c.getPlayer(), source, dropPos);
+2 -2
View File
@@ -753,7 +753,7 @@ public class MapleStatEffect {
applyto.setStance(0);
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.removePlayerFromMap(applyto.getId()), false);
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.spawnPlayerMapobject(applyto), false);
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.spawnPlayerMapObject(applyto), false);
}
}
if (isDispel() && makeChanceResult()) {
@@ -919,7 +919,7 @@ public class MapleStatEffect {
applyto.removeAllCooldownsExcept(Buccaneer.TIME_LEAP, true);
} else if(isHyperBody() && !primary) {
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.removePlayerFromMap(applyto.getId()), false);
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.spawnPlayerMapobject(applyto), false);
applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.spawnPlayerMapObject(applyto), false);
}
return true;
+14 -2
View File
@@ -182,11 +182,13 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
c.announce(MaplePacketCreator.enableActions());
return;
}
int price = (int)Math.min((long)pItem.getPrice() * quantity, Integer.MAX_VALUE);
int price = (int) Math.min((long)pItem.getPrice() * quantity, Integer.MAX_VALUE);
if (c.getPlayer().getMeso() >= price) {
if (MapleInventoryManipulator.checkSpace(c, newItem.getItemId(), newItem.getQuantity(), newItem.getOwner())) {
MapleInventoryManipulator.addFromDrop(c, newItem, false);
c.getPlayer().gainMeso(-price, false);
announceItemSold(newItem, price); // idea thanks to vcoc
synchronized (sold) {
sold.add(new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price));
@@ -226,6 +228,16 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
}
}
private void announceItemSold(Item item, int mesos) {
String qtyStr = (item.getQuantity() > 1) ? " (qty. " + item.getQuantity() + ")" : "";
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
MapleCharacter player = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
if(player != null && player.isLoggedin() && !player.isAwayFromWorld()) {
player.dropMessage(6, "[HIRED MERCHANT] Item '" + ii.getName(item.getItemId()) + "'" + qtyStr + " has been sold for " + mesos + " mesos.");
}
}
public void forceClose() {
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
@@ -508,7 +520,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
return true;
}
public int getChannel() {
return channel;
}
+2 -2
View File
@@ -2131,13 +2131,13 @@ public class MapleMap {
}
}
if (chr.isHidden()) {
broadcastGMMessage(chr, MaplePacketCreator.spawnPlayerMapobject(chr), false);
broadcastGMMessage(chr, MaplePacketCreator.spawnPlayerMapObject(chr), false);
chr.announce(MaplePacketCreator.getGMEffect(0x10, (byte) 1));
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
broadcastGMMessage(chr, MaplePacketCreator.giveForeignBuff(chr.getId(), dsstat), false);
} else {
broadcastMessage(chr, MaplePacketCreator.spawnPlayerMapobject(chr), false);
broadcastMessage(chr, MaplePacketCreator.spawnPlayerMapObject(chr), false);
}
sendObjectPlacement(chr.getClient());
+22 -10
View File
@@ -34,9 +34,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import tools.locks.MonitoredReentrantLock;
import net.SendOpcode;
import net.server.Server;
import server.MapleInventoryManipulator;
import server.maps.AbstractMapleMapObject;
import server.maps.MapleMapObjectType;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.data.output.MaplePacketLittleEndianWriter;
@@ -103,7 +103,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
visitor.setSlot(i);
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, i + 1));
if(i == 2) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(this.getOwner(), 1));
if(i == 2) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(owner, 1));
break;
}
}
@@ -162,7 +162,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
visitorLock.unlock();
}
if(this.getOwner().getPlayerShop() != null) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(this.getOwner(), 4));
if(owner.getPlayerShop() != null) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(owner, 4));
}
}
@@ -205,10 +205,15 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
return;
}
synchronized (c.getPlayer()) {
if (c.getPlayer().getMeso() >= (long) pItem.getPrice() * quantity) {
int price = (int) Math.min((long)pItem.getPrice() * quantity, Integer.MAX_VALUE);
if (c.getPlayer().getMeso() >= price) {
if (MapleInventoryManipulator.addFromDrop(c, newItem, false)) {
c.getPlayer().gainMeso(-pItem.getPrice() * quantity, false);
owner.gainMeso(pItem.getPrice() * quantity, true);
c.getPlayer().gainMeso(-price, false);
announceItemSold(newItem, price); // idea thanks to vcoc
owner.gainMeso(price, true);
pItem.setBundles((short) (pItem.getBundles() - quantity));
if (pItem.getBundles() < 1) {
pItem.setDoesExist(false);
@@ -227,6 +232,13 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
}
}
private void announceItemSold(Item item, int mesos) {
String qtyStr = (item.getQuantity() > 1) ? " (qty. " + item.getQuantity() + ")" : "";
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
owner.dropMessage(6, "[PLAYER SHOP] Item '" + ii.getName(item.getItemId()) + "'" + qtyStr + " has been sold for " + mesos + " mesos.");
}
public void broadcastToVisitors(final byte[] packet) {
visitorLock.lock();
@@ -283,7 +295,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
for(MapleCharacter mc : visitorList) forceRemoveVisitor(mc);
if (owner != null) {
forceRemoveVisitor(getOwner());
forceRemoveVisitor(owner);
}
}
@@ -476,12 +488,12 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
@Override
public void sendDestroyData(MapleClient client) {
client.announce(MaplePacketCreator.removeCharBox(this.getOwner()));
client.announce(MaplePacketCreator.removeCharBox(owner));
}
@Override
public void sendSpawnData(MapleClient client) {
client.announce(MaplePacketCreator.addCharBox(this.getOwner(), 4));
client.announce(MaplePacketCreator.addCharBox(owner, 4));
}
@Override