// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.net.client.handlers; import engine.exception.MsgSendException; import engine.gameManager.ChatManager; import engine.gameManager.DispatchManager; import engine.gameManager.GroupManager; import engine.mbEnums; import engine.mbEnums.DispatchChannel; import engine.net.Dispatch; import engine.net.client.ClientConnection; import engine.net.client.msg.*; import engine.objects.*; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; import static engine.math.FastMath.sqr; public class LootMsgHandler extends AbstractClientMsgHandler { public LootMsgHandler() { super(); } @Override protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { PlayerCharacter player = origin.getPlayerCharacter(); // Member variable declaration LootMsg msg; // Member variable assignment msg = (LootMsg) baseMsg; if (player == null) return true; if (!player.isAlive()) return true; Item item = msg.getItem(); if (item == null) return true; if (item.lootLock.tryLock()) { try { Item itemRet = null; // get current owner int targetType = msg.getTargetType(); int targetID = msg.getTargetID(); if (targetType == mbEnums.GameObjectType.PlayerCharacter.ordinal() || targetType == mbEnums.GameObjectType.Mob.ordinal() || targetType == mbEnums.GameObjectType.Corpse.ordinal()) { } else { //needed for getting contracts for some reason targetType = msg.getSourceID2(); targetID = msg.getUnknown01(); } //can't loot while flying if (player.getAltitude() > 0) return true; AbstractCharacter tar = null; Corpse corpse = null; if (targetType == mbEnums.GameObjectType.PlayerCharacter.ordinal() || targetType == mbEnums.GameObjectType.Mob.ordinal()) { if (targetType == mbEnums.GameObjectType.PlayerCharacter.ordinal()) { tar = PlayerCharacter.getFromCache(targetID); if (tar == null) return true; if (player.getObjectUUID() != tar.getObjectUUID() && ((PlayerCharacter) tar).isInSafeZone()) return true; } else if (targetType == mbEnums.GameObjectType.NPC.ordinal()) tar = NPC.getFromCache(targetID); else if (targetType == mbEnums.GameObjectType.Mob.ordinal()) tar = Mob.getFromCache(targetID); if (tar == null) return true; if (tar.equals(player)) { ErrorPopupMsg.sendErrorMsg(player, "Cannot loot this item."); return true; } if (player.getLoc().distanceSquared2D(tar.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(tar.getLoc()) + " distance."); return true; } //can't loot from someone who is alive. if (AbstractWorldObject.IsAbstractCharacter(tar)) { if (tar.isAlive()) return true; // Logger.error("WorldServer.loot", "Looting from live player"); } if (!GroupManager.goldSplit(player, item, origin, tar)) { if (tar.charItemManager != null) { itemRet = tar.charItemManager.lootItemFromMe(item, player, origin); //Take equipment off mob if (tar.getObjectType() == mbEnums.GameObjectType.Mob && itemRet != null) { Mob mobTarget = (Mob) tar; if (item != null && item.getObjectType() == mbEnums.GameObjectType.MobLoot) { for (Item equip : mobTarget.charItemManager.equipped.values()) { TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.equipSlot); DispatchManager.dispatchMsgToInterestArea(mobTarget, back, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); LootMsg lootMsg = new LootMsg(0, 0, tar.getObjectType().ordinal(), tar.getObjectUUID(), equip); Dispatch dispatch = Dispatch.borrow(player, lootMsg); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); break; } } } } } } else if (targetType == mbEnums.GameObjectType.Corpse.ordinal()) { corpse = Corpse.getCorpse(targetID); if (corpse == null) return true; if (player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(corpse.getLoc()) + " distance."); return true; } //can't loot other players in safe zone. if (corpse.getBelongsToType() == mbEnums.GameObjectType.PlayerCharacter.ordinal()) { if (player.getObjectUUID() == corpse.getBelongsToID()) itemRet = corpse.lootItem(item, player); else if (!GroupManager.goldSplit(player, item, origin, corpse)) { itemRet = corpse.lootItem(item, player); } if (itemRet == null) return true; if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) { // this is done to prevent the temporary goldItem item // (from the mob) from appearing in player's inventory. // It also updates the goldItem quantity display UpdateGoldMsg updateTargetGold = null; if (corpse != null) updateTargetGold = new UpdateGoldMsg(corpse); updateTargetGold.configure(); DispatchManager.dispatchMsgToInterestArea(corpse, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); UpdateGoldMsg ugm = new UpdateGoldMsg(player); ugm.configure(); Dispatch dispatch = Dispatch.borrow(player, ugm); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); // respond back loot message. Try sending to everyone. } else DispatchManager.dispatchMsgToInterestArea(corpse, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); //TODO send group loot message if player is grouped and visible Group group = GroupManager.getGroup(player); if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) { String name = item.getName(); String text = player.getFirstName() + " has looted " + name + '.'; ChatManager.chatGroupInfoCanSee(player, text); } return true; } } else return true; if (itemRet == null) return true; if (item.template.item_type.equals(mbEnums.ItemType.GOLD)) { // this is done to prevent the temporary goldItem item // (from the mob) from appearing in player's inventory. // It also updates the goldItem quantity display UpdateGoldMsg updateTargetGold = null; if (tar != null) updateTargetGold = new UpdateGoldMsg(tar); else if (corpse != null) updateTargetGold = new UpdateGoldMsg(corpse); updateTargetGold.configure(); DispatchManager.dispatchMsgToInterestArea(tar, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); UpdateGoldMsg ugm = new UpdateGoldMsg(player); ugm.configure(); Dispatch dispatch = Dispatch.borrow(player, ugm); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); // respond back loot message. Try sending to everyone. } else { msg.setSourceType1(0); msg.setSourceType2(0); msg.setSourceID1(0); msg.setSourceID2(0); Dispatch dispatch = Dispatch.borrow(player, msg); //DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgToInterestArea(tar, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); LootMsg newItemMsg = new LootMsg(mbEnums.GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, itemRet); dispatch = Dispatch.borrow(player, newItemMsg); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); //player.getCharItemManager().updateInventory(); } //TODO send group loot message if player is grouped and visible Group group = GroupManager.getGroup(player); if (group != null && group.getSplitGold() && (item.template.item_type.equals(mbEnums.ItemType.GOLD) == false)) { String name = item.getName(); String text = player.getFirstName() + " has looted " + name + '.'; ChatManager.chatGroupInfoCanSee(player, text); } } catch (Exception e) { Logger.info(e.getMessage()); } finally { item.lootLock.unlock(); } } return true; } }