forked from MagicBane/Server
				
			
				 3 changed files with 261 additions and 235 deletions
			
			
		@ -0,0 +1,260 @@
				@@ -0,0 +1,260 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      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.ChatManager; | 
				
			||||
import engine.gameManager.GroupManager; | 
				
			||||
import engine.net.Dispatch; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
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(LootMsg.class); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    @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 == Enum.GameObjectType.PlayerCharacter.ordinal() || targetType == Enum.GameObjectType.Mob.ordinal() || targetType == Enum.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 == Enum.GameObjectType.PlayerCharacter.ordinal() || targetType == Enum.GameObjectType.Mob.ordinal()) { | 
				
			||||
 | 
				
			||||
                    if (targetType == Enum.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 == Enum.GameObjectType.NPC.ordinal()) | 
				
			||||
                        tar = NPC.getFromCache(targetID); | 
				
			||||
                    else if (targetType == Enum.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() == Enum.GameObjectType.Mob && itemRet != null) { | 
				
			||||
                                Mob mobTarget = (Mob) tar; | 
				
			||||
 | 
				
			||||
                                if (item != null && item.getObjectType() == Enum.GameObjectType.MobLoot) { | 
				
			||||
 | 
				
			||||
                                    for (Item equip : mobTarget.charItemManager.equipped.values()) { | 
				
			||||
 | 
				
			||||
                                        TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.equipSlot); | 
				
			||||
                                        DispatchMessage.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); | 
				
			||||
                                        DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | 
				
			||||
                                        break; | 
				
			||||
                                    } | 
				
			||||
                                } | 
				
			||||
                            } | 
				
			||||
                        } | 
				
			||||
 | 
				
			||||
                    } | 
				
			||||
                } else if (targetType == Enum.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() == Enum.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(engine.Enum.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(); | 
				
			||||
                            DispatchMessage.dispatchMsgToInterestArea(corpse, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); | 
				
			||||
 | 
				
			||||
                            UpdateGoldMsg ugm = new UpdateGoldMsg(player); | 
				
			||||
                            ugm.configure(); | 
				
			||||
                            Dispatch dispatch = Dispatch.borrow(player, ugm); | 
				
			||||
                            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); | 
				
			||||
 | 
				
			||||
                            // respond back loot message. Try sending to everyone.
 | 
				
			||||
 | 
				
			||||
                        } else | 
				
			||||
                            DispatchMessage.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(engine.Enum.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(engine.Enum.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(); | 
				
			||||
                    DispatchMessage.dispatchMsgToInterestArea(tar, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); | 
				
			||||
 | 
				
			||||
                    UpdateGoldMsg ugm = new UpdateGoldMsg(player); | 
				
			||||
                    ugm.configure(); | 
				
			||||
                    Dispatch dispatch = Dispatch.borrow(player, ugm); | 
				
			||||
                    DispatchMessage.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);
 | 
				
			||||
                    DispatchMessage.dispatchMsgToInterestArea(tar, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); | 
				
			||||
                    LootMsg newItemMsg = new LootMsg(Enum.GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, itemRet); | 
				
			||||
                    dispatch = Dispatch.borrow(player, newItemMsg); | 
				
			||||
                    DispatchMessage.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(engine.Enum.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; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue