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.
414 lines
15 KiB
414 lines
15 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// Magicbane Emulator Project © 2013 - 2022 |
|
// www.magicbane.com |
|
|
|
|
|
package engine.net.client.handlers; |
|
|
|
import engine.exception.MsgSendException; |
|
import engine.gameManager.ChatManager; |
|
import engine.gameManager.DbManager; |
|
import engine.gameManager.ForgeManager; |
|
import engine.loot.WorkOrder; |
|
import engine.mbEnums; |
|
import engine.mbEnums.GameObjectType; |
|
import engine.mbEnums.ItemType; |
|
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.ItemProductionMsg; |
|
import engine.net.client.msg.ManageNPCMsg; |
|
import engine.objects.*; |
|
import org.pmw.tinylog.Logger; |
|
|
|
import java.util.HashMap; |
|
|
|
/* |
|
* @Summary: Processes application protocol message which modifies |
|
* hireling inventory through rolling, junking or depositing. |
|
*/ |
|
|
|
public class ItemProductionMsgHandler extends AbstractClientMsgHandler { |
|
|
|
public ItemProductionMsgHandler() { |
|
super(ItemProductionMsg.class); |
|
} |
|
|
|
@Override |
|
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { |
|
|
|
// Member variable declaration |
|
|
|
PlayerCharacter player; |
|
NPC vendorNPC; |
|
ItemProductionMsg msg; |
|
Dispatch dispatch; |
|
|
|
// Member variable assignment |
|
|
|
msg = (ItemProductionMsg) baseMsg; |
|
player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return true; |
|
|
|
// Grab reference to vendor we are interacting with |
|
|
|
vendorNPC = (NPC) DbManager.getObject(mbEnums.GameObjectType.NPC, msg.npcUUID); |
|
|
|
// Oops? |
|
|
|
if (vendorNPC == null) |
|
return true; |
|
|
|
// Process Request |
|
|
|
switch (msg.actionType) { |
|
|
|
case PRODUCE: |
|
|
|
// Create new work order |
|
|
|
WorkOrder workOrder = new WorkOrder(); |
|
workOrder.total_to_produce = msg.total_to_produce; |
|
workOrder.vendor = vendorNPC; |
|
workOrder.templateID = msg.itemUUID; |
|
workOrder.prefixToken = msg.pToken; |
|
workOrder.suffixToken = msg.sToken; |
|
workOrder.item_name_override = msg.name; |
|
workOrder.multiple_slot_request = msg.size; |
|
|
|
// Submit workOder to begin rolling items |
|
|
|
int validation_result = ForgeManager.submit(workOrder); |
|
|
|
// workOrder could not be completed |
|
// Report back to the user the reason why |
|
|
|
if (validation_result != 0) { |
|
ErrorPopupMsg.sendErrorPopup(player, validation_result); |
|
return true; |
|
} |
|
|
|
break; |
|
case JUNK: |
|
junkItem(msg.itemUUID, vendorNPC, origin); |
|
break; |
|
case RECYCLE: |
|
recycleItem(msg.items, vendorNPC, origin); |
|
msg.actionType = mbEnums.ProductionActionType.TAKE; |
|
dispatch = Dispatch.borrow(player, msg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
break; |
|
case COMPLETE: |
|
// todo fix vendorNPC.completeItem(msg.itemUUID); |
|
break; |
|
case DEPOSIT: |
|
depositItem(msg.itemUUID, vendorNPC, origin); |
|
break; |
|
case SETPRICE: |
|
setItemPrice(msg.itemType, msg.itemUUID, msg.itemPrice, vendorNPC, origin); |
|
break; |
|
case TAKE: |
|
takeItem(msg.items, vendorNPC, origin); |
|
dispatch = Dispatch.borrow(player, msg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
break; |
|
} |
|
return true; |
|
} |
|
|
|
private static void setItemPrice(int itemType, int itemUUID, int itemPrice, NPC vendor, ClientConnection origin) { |
|
|
|
Item targetItem; |
|
ItemProductionMsg outMsg; |
|
Dispatch dispatch; |
|
|
|
PlayerCharacter player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return; |
|
|
|
if (itemType == GameObjectType.Item.ordinal()) |
|
targetItem = Item.getFromCache(itemUUID); |
|
else if (itemType == GameObjectType.MobLoot.ordinal()) |
|
targetItem = MobLoot.getFromCache(itemUUID); |
|
else |
|
targetItem = null; |
|
|
|
if (targetItem == null) |
|
return; |
|
|
|
if (targetItem.getObjectType() == GameObjectType.Item) { |
|
if (!DbManager.ItemQueries.UPDATE_VALUE(targetItem, itemPrice)) { |
|
ChatManager.chatInfoError(origin.getPlayerCharacter(), "Failed to set price! Contact CCR For help."); |
|
return; |
|
} |
|
targetItem.setValue(itemPrice); |
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.DEPOSIT, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
|
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.SETPRICE, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
} else if (targetItem.getObjectType() == GameObjectType.MobLoot) { |
|
MobLoot mobLoot = (MobLoot) targetItem; |
|
if (!DbManager.NPCQueries.UPDATE_ITEM_PRICE(mobLoot.getObjectUUID(), vendor.getObjectUUID(), itemPrice)) { |
|
ChatManager.chatInfoError(origin.getPlayerCharacter(), "Failed to set price! Contact CCR For help."); |
|
return; |
|
} |
|
targetItem.setValue(itemPrice); |
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.DEPOSIT, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
|
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.SETPRICE, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
} |
|
} |
|
|
|
// Method sets the price on an item in the vendor inventory |
|
|
|
private static void depositItem(int itemUUID, NPC vendor, ClientConnection origin) { |
|
|
|
Item targetItem; |
|
ItemProductionMsg outMsg; |
|
CharacterItemManager itemMan; |
|
Dispatch dispatch; |
|
|
|
PlayerCharacter player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return; |
|
|
|
if (origin.sellLock.tryLock()) { |
|
try { |
|
targetItem = Item.getFromCache(itemUUID); |
|
|
|
if (targetItem == null) |
|
return; |
|
|
|
if (targetItem.template.item_type.equals(ItemType.GOLD)) |
|
return; |
|
|
|
if (!vendor.charItemManager.hasRoomInventory(targetItem.template.item_wt)) { |
|
ErrorPopupMsg.sendErrorPopup(player, 21); |
|
return; |
|
} |
|
|
|
itemMan = origin.getPlayerCharacter().charItemManager; |
|
|
|
if (itemMan == null) |
|
return; |
|
|
|
if (vendor.charItemManager.getInventoryWeight() > 500) { |
|
ErrorPopupMsg.sendErrorPopup(player, 21); |
|
return; |
|
} |
|
|
|
if (!targetItem.validForInventory(origin, player, itemMan)) { |
|
ErrorPopupMsg.sendErrorPopup(player, 19); |
|
return; |
|
} |
|
|
|
// Transfer item from player to vendor's inventory |
|
|
|
if (!itemMan.sellToNPC(targetItem, vendor)) { |
|
ErrorPopupMsg.sendErrorPopup(player, 109); |
|
return; |
|
} |
|
|
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.DEPOSIT, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
|
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.CONFIRM_DEPOSIT, true); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
|
|
origin.getPlayerCharacter().charItemManager.updateInventory(); |
|
} catch (Exception e) { |
|
Logger.error(e); |
|
} finally { |
|
origin.sellLock.unlock(); |
|
} |
|
} |
|
|
|
} |
|
|
|
// Method completes an item that has been previously rolled |
|
// adding it to the NPC's inventory |
|
|
|
private static void recycleItem(HashMap<Integer, Integer> itemList, NPC vendor, ClientConnection origin) { |
|
|
|
Item targetItem; |
|
ItemProductionMsg outMsg; |
|
int totalValue = 0; |
|
Dispatch dispatch; |
|
|
|
if (vendor.getBuilding() == null) |
|
return; |
|
|
|
PlayerCharacter player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return; |
|
|
|
if (itemList == null) |
|
return; |
|
|
|
if (origin.sellLock.tryLock()) { |
|
try { |
|
|
|
|
|
for (int itemUUID : itemList.keySet()) { |
|
int itemValue = 0; |
|
|
|
int type = itemList.get(itemUUID); |
|
|
|
if (type == GameObjectType.Item.ordinal()) |
|
targetItem = Item.getFromCache(itemUUID); |
|
else |
|
targetItem = MobLoot.getFromCache(itemUUID); |
|
|
|
if (targetItem == null) |
|
continue; |
|
|
|
if (targetItem.template.item_type.equals(ItemType.GOLD)) |
|
return; |
|
|
|
if (!vendor.charItemManager.doesCharOwnThisItem(targetItem.getObjectUUID())) |
|
continue; |
|
if (vendor.charItemManager.inventoryContains(targetItem) == false) |
|
continue; |
|
|
|
itemValue = targetItem.template.item_value; |
|
|
|
if (vendor.getBuilding().getStrongboxValue() + itemValue > vendor.getBuilding().getMaxGold()) { |
|
ErrorPopupMsg.sendErrorPopup(player, 201); |
|
break; |
|
} |
|
|
|
switch (targetItem.template.item_type) { |
|
case EMPLOYMENTCONTRACT: |
|
case CHARTER: |
|
case DEED: |
|
case REALMCHARTER: |
|
case SCROLL: |
|
case POTION: |
|
continue; |
|
} |
|
totalValue += itemValue; |
|
vendor.charItemManager.recycle(targetItem); |
|
|
|
outMsg = new ItemProductionMsg(vendor.getBuilding(), vendor, targetItem, mbEnums.ProductionActionType.TAKE, true); |
|
|
|
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
} |
|
|
|
// Refund a portion of the gold |
|
|
|
if (!vendor.getBuilding().transferGold(totalValue, false)) |
|
return; |
|
|
|
} catch (Exception e) { |
|
Logger.error(e); |
|
} finally { |
|
origin.sellLock.unlock(); |
|
} |
|
} |
|
} |
|
|
|
// Method handles recycling of an item |
|
|
|
private static void junkItem(int itemUUID, NPC vendor, ClientConnection origin) { |
|
|
|
MobLoot targetItem; |
|
ManageNPCMsg outMsg; |
|
Dispatch dispatch; |
|
|
|
if (origin.sellLock.tryLock()) { |
|
try { |
|
targetItem = MobLoot.getFromCache(itemUUID); |
|
|
|
PlayerCharacter player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return; |
|
|
|
// junk nothing? |
|
|
|
if (targetItem == null) |
|
return; |
|
|
|
if (!ForgeManager.vendorItemLookup.get(vendor).contains(targetItem)) |
|
return; |
|
|
|
// Cannot junk items without a forge! |
|
|
|
if (vendor.getBuilding() == null) |
|
return; |
|
|
|
// Delete the item and cancel any pending rolling timer jobs |
|
|
|
targetItem.recycle(vendor); |
|
// todo fix vendor.removeItemFromForge(targetItem); |
|
|
|
// Refresh vendor's inventory to client |
|
|
|
outMsg = new ManageNPCMsg(vendor); |
|
outMsg.setMessageType(1); |
|
dispatch = Dispatch.borrow(player, outMsg); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); |
|
} finally { |
|
origin.sellLock.unlock(); |
|
} |
|
} |
|
|
|
} |
|
|
|
private static void takeItem(HashMap<Integer, Integer> itemList, NPC vendor, ClientConnection origin) { |
|
|
|
Item targetItem; |
|
PlayerCharacter player = origin.getPlayerCharacter(); |
|
|
|
if (player == null) |
|
return; |
|
|
|
for (int itemUUID : itemList.keySet()) { |
|
|
|
int type = itemList.get(itemUUID); |
|
if (type == GameObjectType.Item.ordinal()) { |
|
targetItem = Item.getFromCache(itemUUID); |
|
|
|
} else |
|
targetItem = MobLoot.getFromCache(itemUUID); |
|
|
|
if (targetItem == null) |
|
return; |
|
|
|
if (targetItem.template.item_type.equals(ItemType.GOLD)) |
|
return; |
|
if (vendor.charItemManager.inventoryContains(targetItem) == false) |
|
return; |
|
|
|
if (player.charItemManager.hasRoomInventory(targetItem.template.item_wt) == false) |
|
return; |
|
|
|
player.charItemManager.buyFromNPC(targetItem, vendor); |
|
} |
|
|
|
player.charItemManager.updateInventory(); |
|
|
|
} |
|
|
|
}
|
|
|