// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.net.client.handlers; import engine.Enum; import engine.Enum.DispatchChannel; import engine.exception.MsgSendException; import engine.gameManager.SessionManager; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.ClientConnection; import engine.net.client.msg.BuyFromNPCMsg; import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ErrorPopupMsg; import engine.objects.*; import java.util.ArrayList; public class BuyFromNPCMsgHandler extends AbstractClientMsgHandler { public BuyFromNPCMsgHandler() { super(BuyFromNPCMsg.class); } @Override protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { // Member variable declaration BuyFromNPCMsg buyFromNPCMsg; // Member variable assignment buyFromNPCMsg = (BuyFromNPCMsg) baseMsg; PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin); if (sourcePlayer == null) return true; if (origin.buyLock.tryLock()) { try { CharacterItemManager itemMan = sourcePlayer.getCharItemManager(); if (itemMan == null) return true; NPC npc = NPC.getFromCache(buyFromNPCMsg.getNPCID()); if (npc == null) return true; Item gold = itemMan.getGoldInventory(); if (gold == null) return true; Item buy = null; if (buyFromNPCMsg.getItemType() == Enum.GameObjectType.Item.ordinal()) { ArrayList sellInventory = npc.getContract().getSellInventory(); if (sellInventory == null) return true; for (Item me : sellInventory) { if (me.getObjectUUID() == buyFromNPCMsg.getItemID()) { //test room available for item if (!itemMan.hasRoomInventory(me.template.item_wt)) return true; int cost = me.getMagicValue(); float bargain = sourcePlayer.getBargain(); float profit = npc.getSellPercent(sourcePlayer) - bargain; if (profit < 1) profit = 1; cost *= profit; if (gold.getNumOfItems() - cost < 0) { //dont' have enough goldItem exit! // chatMan.chatSystemInfo(pc, "" + "You dont have enough gold."); return true; } Building building = (!npc.isStatic()) ? npc.getBuilding() : null; if (building != null && building.getProtectionState().equals(Enum.ProtectionState.NPC)) building = null; int buildingDeposit = cost - me.getMagicValue(); if (building != null && (building.getStrongboxValue() + buildingDeposit) > building.getMaxGold()) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); return true; } if (!itemMan.buyFromNPC(building, cost, buildingDeposit)) { // chatMan.chatSystemInfo(pc, "" + "You Failed to buy the item."); return true; } buy = Item.createItemForPlayer(sourcePlayer, me.templateID); if (buy != null) { me.transferEnchants(buy); itemMan.addItemToInventory(buy); //itemMan.updateInventory(); } } } } else if (buyFromNPCMsg.getItemType() == Enum.GameObjectType.Item.ordinal()) { CharacterItemManager npcCim = npc.getCharItemManager(); if (npcCim == null) return true; buy = Item.getFromCache(buyFromNPCMsg.getItemID()); if (buy == null) return true; if (!npcCim.inventoryContains(buy)) return true; //test room available for item if (!itemMan.hasRoomInventory(buy.template.item_wt)) return true; //TODO test cost and subtract goldItem //TODO CHnage this if we ever put NPc city npcs in buildings. int cost = buy.template.item_value; if (buy.isID() || buy.isCustomValue()) cost = buy.getMagicValue(); float bargain = sourcePlayer.getBargain(); float profit = npc.getSellPercent(sourcePlayer) - bargain; if (profit < 1) profit = 1; if (!buy.isCustomValue()) cost *= profit; else cost = buy.getValue(); if (gold.getNumOfItems() - cost < 0) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold return true; } Building building = (!npc.isStatic()) ? npc.getBuilding() : null; if (building != null) if (building.getProtectionState().equals(Enum.ProtectionState.NPC)) building = null; int buildingDeposit = cost; if (building != null && (building.getStrongboxValue() + buildingDeposit) > building.getMaxGold()) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); return true; } if (!itemMan.buyFromNPC(building, cost, buildingDeposit)) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 110); return true; } if (buy != null) itemMan.buyFromNPC(buy, npc); } else if (buyFromNPCMsg.getItemType() == Enum.GameObjectType.MobLoot.ordinal()) { CharacterItemManager npcCim = npc.getCharItemManager(); if (npcCim == null) return true; buy = MobLoot.getFromCache(buyFromNPCMsg.getItemID()); if (buy == null) return true; if (!npcCim.inventoryContains(buy)) return true; //test room available for item if (!itemMan.hasRoomInventory(buy.template.item_wt)) return true; //TODO test cost and subtract goldItem //TODO CHnage this if we ever put NPc city npcs in buildings. int cost = buy.getMagicValue(); cost *= npc.getSellPercent(sourcePlayer); if (gold.getNumOfItems() - cost < 0) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold return true; } Building building = (!npc.isStatic()) ? npc.getBuilding() : null; if (building != null && building.getProtectionState().equals(Enum.ProtectionState.NPC)) building = null; int buildingDeposit = cost; if (building != null && (building.getStrongboxValue() + buildingDeposit) > building.getMaxGold()) { ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); return true; } if (!itemMan.buyFromNPC(building, cost, buildingDeposit)) return true; if (buy != null) itemMan.buyFromNPC(buy, npc); } else return true; if (buy != null) { buyFromNPCMsg.setItem(buy); //send the buy message back to update player // msg.setItemType(buy.getObjectType().ordinal()); // msg.setItemID(buy.getObjectUUID()); Dispatch dispatch = Dispatch.borrow(sourcePlayer, buyFromNPCMsg); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); itemMan.updateInventory(); } } finally { origin.buyLock.unlock(); } } else { ErrorPopupMsg.sendErrorPopup(origin.getPlayerCharacter(), 12); // All production slots taken } return true; } }