forked from MagicBane/Server
FatBoy-DOTC
6 months ago
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