forked from MagicBane/Server
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							208 lines
						
					
					
						
							7.3 KiB
						
					
					
				
			
		
		
	
	
							208 lines
						
					
					
						
							7.3 KiB
						
					
					
				| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ . | |
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· | |
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ | |
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ | |
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀ | |
| //      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.ClientNetMsg; | |
| import engine.net.client.msg.ErrorPopupMsg; | |
| import engine.net.client.msg.UpdateGoldMsg; | |
| import engine.net.client.msg.VendorSellMsg; | |
| import engine.objects.*; | |
|  | |
| import java.util.ArrayList; | |
|  | |
| public class VendorSellMsgHandler extends AbstractClientMsgHandler { | |
|  | |
|     public VendorSellMsgHandler() { | |
|         super(VendorSellMsg.class); | |
|     } | |
|  | |
|     @Override | |
|     protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { | |
|  | |
|         PlayerCharacter pc = origin.getPlayerCharacter(); | |
|         PlayerCharacter player = SessionManager.getPlayerCharacter(origin); | |
|         Dispatch dispatch; | |
|  | |
|         if (player == null) | |
|             return true; | |
|  | |
|         CharacterItemManager itemMan = player.charItemManager; | |
|  | |
|         if (itemMan == null) | |
|             return true; | |
|  | |
|         VendorSellMsg vendorSellMsg = (VendorSellMsg) baseMsg; | |
|  | |
|         NPC npc = NPC.getFromCache(vendorSellMsg.getNPCID()); | |
|  | |
|         if (npc == null) | |
|             return true; | |
|  | |
|         Item gold = itemMan.getGoldInventory(); | |
|  | |
|         if (gold == null) | |
|             return true; | |
|  | |
|         if (origin.sellLock.tryLock()) { | |
|             try { | |
|                 Item sell; | |
|                 int cost = 0; | |
|  | |
|  | |
|                 if (npc.charItemManager.getInventoryCount() > 150) { | |
|                     if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID == 0) { | |
|                         ArrayList<Item> inv = npc.getInventory(); | |
|                         for (int i = 0; i < 20; i++) { | |
|                             try { | |
|                                 Item toRemove = inv.get(i); | |
|                                 if (toRemove != null) | |
|                                     npc.charItemManager.delete(toRemove); | |
|                             } catch (Exception e) { | |
|                                 break; | |
|                             } | |
|  | |
|                         } | |
|                     } | |
|  | |
|                 } | |
|  | |
|                 // Early exit sanity check | |
|  | |
|                 if (vendorSellMsg.getItemType() == Enum.GameObjectType.Item.ordinal() == false) | |
|                     return true; | |
|  | |
|                 sell = Item.getFromCache(vendorSellMsg.getItemID()); | |
|  | |
|                 if (sell == null) | |
|                     return true; | |
|  | |
|                 //get item to sell | |
|  | |
|                 if (sell.template == null) | |
|                     return true; | |
|  | |
|                 if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0) | |
|                     if (!npc.charItemManager.hasRoomInventory(sell.template.item_wt)) { | |
|                         ErrorPopupMsg.sendErrorPopup(player, 21); | |
|                         return true; | |
|                     } | |
|  | |
|                 if (!sell.validForInventory(origin, player, itemMan)) | |
|                     return true; | |
|  | |
|                 //get goldItem cost to sell | |
|  | |
|  | |
|                 cost = sell.template.item_value; | |
|  | |
|                 //apply damaged value reduction | |
|                 float durabilityCurrent = (short) sell.durabilityCurrent; | |
|                 float durabilityMax = sell.template.item_health_full; | |
|                 float damagedModifier = durabilityCurrent / durabilityMax; | |
|                 cost *= damagedModifier; | |
|                 float bargain = player.getBargain(); | |
|  | |
|                 float profit = npc.getBuyPercent(player) + bargain; | |
|  | |
|                 if (profit > 1) | |
|                     profit = 1; | |
|  | |
|  | |
|                 cost *= profit; | |
|  | |
|                 if (gold.getNumOfItems() + cost > 10000000) | |
|                     return true; | |
|  | |
|                 if (gold.getNumOfItems() + cost < 0) | |
|                     return true; | |
|  | |
|                 //TODO make sure npc can buy item type | |
|                 //test room available for item on npc | |
|  | |
|                 //                                 if (!npc.isStatic() && npc.getCharItemManager().getInventoryCount() > 150) { | |
|                 //                                   //  chatMan.chatSystemInfo(pc, "This vendor's inventory is full"); | |
|                 //                                     return; | |
|                 //                                 } | |
|  | |
|                 //make sure item is in player inventory | |
|  | |
|                 Building building = (!npc.isStatic()) ? npc.getBuilding() : null; | |
|  | |
|                 if (building != null && building.getProtectionState().equals(Enum.ProtectionState.NPC)) | |
|                     building = null; | |
|  | |
|                 if (npc.getParentZone().playerCityUUID == 0) | |
|                     building = null; | |
|  | |
|                 //make sure npc can afford item | |
|  | |
|                 if (building != null && !building.hasFunds(cost)) { | |
|                     ErrorPopupMsg.sendErrorPopup(player, 17); | |
|                     return true; | |
|                 } | |
|  | |
|                 if (building != null && (building.getStrongboxValue() - cost) < 0) { | |
|                     ErrorPopupMsg.sendErrorPopup(player, 17); | |
|                     return true; | |
|                 } | |
|  | |
|                 //TODO transfer item and goldItem transfer should be handled together incase failure | |
|                 //transfer the item | |
|  | |
|                 if (!itemMan.sellToNPC(sell, npc)) | |
|                     return true; | |
|  | |
|                 if (!itemMan.sellToNPC(building, cost, sell)) | |
|                     return true; | |
|  | |
|                 //handle goldItem transfer | |
|  | |
|                 if (sell == null) | |
|                     return true; | |
|  | |
|                 // ***REFACTOR: SellToNpc sends this message, is this a duplicate? | |
|  | |
|                 //update player's goldItem count | |
|                 UpdateGoldMsg ugm = new UpdateGoldMsg(player); | |
|                 ugm.configure(); | |
|  | |
|                 dispatch = Dispatch.borrow(player, ugm); | |
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | |
|  | |
|                 //send the sell message back to update player | |
|                 vendorSellMsg.setItemType(sell.getObjectType().ordinal()); | |
|                 vendorSellMsg.setItemID(sell.getObjectUUID()); | |
|                 vendorSellMsg.setUnknown01(cost); //not sure if this is correct | |
|  | |
|                 dispatch = Dispatch.borrow(player, vendorSellMsg); | |
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | |
|  | |
|             } finally { | |
|                 origin.sellLock.unlock(); | |
|             } | |
|         } else { | |
|             ErrorPopupMsg.sendErrorPopup(player, 12); | |
|         } | |
|  | |
|         // Send ping to client | |
|  | |
|         dispatch = Dispatch.borrow(pc, vendorSellMsg); | |
|         DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | |
|  | |
|         return true; | |
|     } | |
|  | |
| } |