forked from MagicBane/Server
				
			
				 2 changed files with 200 additions and 230 deletions
			
			
		@ -0,0 +1,199 @@ | 
				
			|||||||
 | 
					package engine.gameManager; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import engine.Enum; | 
				
			||||||
 | 
					import engine.exception.MsgSendException; | 
				
			||||||
 | 
					import engine.net.Dispatch; | 
				
			||||||
 | 
					import engine.net.DispatchMessage; | 
				
			||||||
 | 
					import engine.net.client.ClientConnection; | 
				
			||||||
 | 
					import engine.net.client.msg.LootMsg; | 
				
			||||||
 | 
					import engine.net.client.msg.TransferItemFromEquipToInventoryMsg; | 
				
			||||||
 | 
					import engine.net.client.msg.UpdateGoldMsg; | 
				
			||||||
 | 
					import engine.objects.*; | 
				
			||||||
 | 
					import engine.server.MBServerStatics; | 
				
			||||||
 | 
					import org.pmw.tinylog.Logger; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static engine.math.FastMath.sqr; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class LootActionManager { | 
				
			||||||
 | 
					    public static void loot(LootMsg msg, ClientConnection origin) throws MsgSendException { | 
				
			||||||
 | 
					        PlayerCharacter player = SessionManager.getPlayerCharacter(origin); | 
				
			||||||
 | 
					        if (player == null || !player.isAlive() || player.getAltitude() > 0) { | 
				
			||||||
 | 
					            return; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Item item = msg.getItem(); | 
				
			||||||
 | 
					        if (item == null) { | 
				
			||||||
 | 
					            return; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (item.lootLock.tryLock()) { | 
				
			||||||
 | 
					            try { | 
				
			||||||
 | 
					                handleLoot(msg, player, item, origin); | 
				
			||||||
 | 
					            } catch (Exception e) { | 
				
			||||||
 | 
					                Logger.info(e.getMessage()); | 
				
			||||||
 | 
					            } finally { | 
				
			||||||
 | 
					                item.lootLock.unlock(); | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void handleLoot(LootMsg msg, PlayerCharacter player, Item item, ClientConnection origin) { | 
				
			||||||
 | 
					        int targetType = msg.getTargetType(); | 
				
			||||||
 | 
					        int targetID = msg.getTargetID(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!isValidTargetType(targetType)) { | 
				
			||||||
 | 
					            targetType = msg.getSourceID2(); | 
				
			||||||
 | 
					            targetID = msg.getUnknown01(); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        AbstractCharacter targetCharacter; | 
				
			||||||
 | 
					        Corpse corpse; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isCharacterOrMob(targetType)) { | 
				
			||||||
 | 
					            targetCharacter = getTargetCharacter(targetType, targetID); | 
				
			||||||
 | 
					            if (targetCharacter == null || isInvalidLootTarget(player, targetCharacter)) { | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!lootCharacter(player, item, origin, targetCharacter)) { | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            handleCharacterLoot(player, msg, item, targetCharacter); | 
				
			||||||
 | 
					        } else if (targetType == Enum.GameObjectType.Corpse.ordinal()) { | 
				
			||||||
 | 
					            corpse = Corpse.getCorpse(targetID); | 
				
			||||||
 | 
					            if (corpse == null || isTooFarToLoot(player, corpse)) { | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!lootCorpse(player, item, origin, corpse)) { | 
				
			||||||
 | 
					                return; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            handleCorpseLoot(player, msg, item, corpse); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isValidTargetType(int targetType) { | 
				
			||||||
 | 
					        return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || | 
				
			||||||
 | 
					                targetType == Enum.GameObjectType.Mob.ordinal() || | 
				
			||||||
 | 
					                targetType == Enum.GameObjectType.Corpse.ordinal(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isCharacterOrMob(int targetType) { | 
				
			||||||
 | 
					        return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || | 
				
			||||||
 | 
					                targetType == Enum.GameObjectType.Mob.ordinal() || | 
				
			||||||
 | 
					                targetType == Enum.GameObjectType.NPC.ordinal(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static AbstractCharacter getTargetCharacter(int targetType, int targetID) { | 
				
			||||||
 | 
					        if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) { | 
				
			||||||
 | 
					            return PlayerCharacter.getFromCache(targetID); | 
				
			||||||
 | 
					        } else if (targetType == Enum.GameObjectType.NPC.ordinal()) { | 
				
			||||||
 | 
					            return NPC.getFromCache(targetID); | 
				
			||||||
 | 
					        } else if (targetType == Enum.GameObjectType.Mob.ordinal()) { | 
				
			||||||
 | 
					            return Mob.getFromCache(targetID); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return null; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isInvalidLootTarget(PlayerCharacter player, AbstractCharacter target) { | 
				
			||||||
 | 
					        return target.equals(player) || | 
				
			||||||
 | 
					                (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && | 
				
			||||||
 | 
					                        player.getObjectUUID() != target.getObjectUUID() && | 
				
			||||||
 | 
					                        ((PlayerCharacter) target).isInSafeZone()) || | 
				
			||||||
 | 
					                player.getLoc().distanceSquared2D(target.getLoc()) > sqr(MBServerStatics.LOOT_RANGE) || | 
				
			||||||
 | 
					                target.isAlive(); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isTooFarToLoot(PlayerCharacter player, Corpse corpse) { | 
				
			||||||
 | 
					        return player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean lootCharacter(PlayerCharacter player, Item item, ClientConnection origin, AbstractCharacter target) { | 
				
			||||||
 | 
					        if (!GroupManager.goldSplit(player, item, origin, target)) { | 
				
			||||||
 | 
					            if (target.getCharItemManager() != null) { | 
				
			||||||
 | 
					                Item itemRet = target.getCharItemManager().lootItemFromMe(item, player, origin); | 
				
			||||||
 | 
					                if (target.getObjectType() == Enum.GameObjectType.Mob && itemRet != null && item.getObjectType() == Enum.GameObjectType.MobLoot) { | 
				
			||||||
 | 
					                    handleMobEquipmentLoot(player, target); | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					                return itemRet != null; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return false; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void handleMobEquipmentLoot(PlayerCharacter player, AbstractCharacter target) { | 
				
			||||||
 | 
					        Mob mobTarget = (Mob) target; | 
				
			||||||
 | 
					        for (MobEquipment equip : mobTarget.getEquip().values()) { | 
				
			||||||
 | 
					            TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.getSlot()); | 
				
			||||||
 | 
					            DispatchMessage.dispatchMsgToInterestArea(mobTarget, back, Enum.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LootMsg lootMsg = new LootMsg(0, 0, target.getObjectType().ordinal(), target.getObjectUUID(), equip); | 
				
			||||||
 | 
					            Dispatch dispatch = Dispatch.borrow(player, lootMsg); | 
				
			||||||
 | 
					            DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); | 
				
			||||||
 | 
					            break; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean lootCorpse(PlayerCharacter player, Item item, ClientConnection origin, Corpse corpse) { | 
				
			||||||
 | 
					        Item itemRet = null; | 
				
			||||||
 | 
					        if (player.getObjectUUID() == corpse.getBelongsToID()) { | 
				
			||||||
 | 
					            itemRet = corpse.lootItem(item, player); | 
				
			||||||
 | 
					        } else if (!GroupManager.goldSplit(player, item, origin, corpse)) { | 
				
			||||||
 | 
					            itemRet = corpse.lootItem(item, player); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return itemRet != null; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void handleCharacterLoot(PlayerCharacter player, LootMsg msg, Item item, AbstractCharacter target) { | 
				
			||||||
 | 
					        if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { | 
				
			||||||
 | 
					            updateGold(player, target); | 
				
			||||||
 | 
					        } else { | 
				
			||||||
 | 
					            dispatchLootMessage(player, msg, target, item); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        sendGroupLootMessage(player, item); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void handleCorpseLoot(PlayerCharacter player, LootMsg msg, Item item, Corpse corpse) { | 
				
			||||||
 | 
					        if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { | 
				
			||||||
 | 
					            updateGold(player, corpse); | 
				
			||||||
 | 
					        } else { | 
				
			||||||
 | 
					            DispatchMessage.dispatchMsgToInterestArea(corpse, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        sendGroupLootMessage(player, item); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void updateGold(PlayerCharacter player, AbstractWorldObject target) { | 
				
			||||||
 | 
					        UpdateGoldMsg updateTargetGold = new UpdateGoldMsg(target); | 
				
			||||||
 | 
					        updateTargetGold.configure(); | 
				
			||||||
 | 
					        DispatchMessage.dispatchMsgToInterestArea(target, updateTargetGold, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        UpdateGoldMsg ugm = new UpdateGoldMsg(player); | 
				
			||||||
 | 
					        ugm.configure(); | 
				
			||||||
 | 
					        Dispatch dispatch = Dispatch.borrow(player, ugm); | 
				
			||||||
 | 
					        DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void dispatchLootMessage(PlayerCharacter player, LootMsg msg, AbstractCharacter target, Item item) { | 
				
			||||||
 | 
					        msg.setSourceType1(0); | 
				
			||||||
 | 
					        msg.setSourceType2(0); | 
				
			||||||
 | 
					        msg.setSourceID1(0); | 
				
			||||||
 | 
					        msg.setSourceID2(0); | 
				
			||||||
 | 
					        Dispatch dispatch = Dispatch.borrow(player, msg); | 
				
			||||||
 | 
					        DispatchMessage.dispatchMsgToInterestArea(target, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LootMsg newItemMsg = new LootMsg(Enum.GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, item); | 
				
			||||||
 | 
					        dispatch = Dispatch.borrow(player, newItemMsg); | 
				
			||||||
 | 
					        DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void sendGroupLootMessage(PlayerCharacter player, Item item) { | 
				
			||||||
 | 
					        Group group = GroupManager.getGroup(player); | 
				
			||||||
 | 
					        if (group != null && group.getSplitGold() && !item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { | 
				
			||||||
 | 
					            String name = item.getName(); | 
				
			||||||
 | 
					            String text = player.getFirstName() + " has looted " + name + '.'; | 
				
			||||||
 | 
					            ChatManager.chatGroupInfoCanSee(player, text); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue