Skip to content

Commit

Permalink
Implement item drop. Drop supported via drag to map renderer or drop …
Browse files Browse the repository at this point in the history
…item button.
  • Loading branch information
ethanmoffat committed Mar 29, 2022
1 parent 6cebd7b commit 3f6ee12
Show file tree
Hide file tree
Showing 19 changed files with 323 additions and 314 deletions.
4 changes: 4 additions & 0 deletions EOBot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public void TakeItemFromMap(short id, int amountTaken)
ConsoleHelper.WriteMessage(ConsoleHelper.Type.Item, $"{weight,3}/{maxWeight,3} - weight - {inventoryCount.Amount} in inventory");
}

public void DropItem(short id, int amountDropped)
{
}

public void JunkItem(short id, int amountRemoved)
{
var inventoryCount = _characterInventoryProvider.ItemInventory.SingleOrDefault(x => x.ItemID == id);
Expand Down
13 changes: 13 additions & 0 deletions EOLib/Domain/Item/ItemActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ public void UnequipItem(short itemId, bool alternateLocation)
_packetSendService.SendPacket(packet);
}

public void DropItem(short itemId, int amount, MapCoordinate dropPoint)
{
var packet = new PacketBuilder(PacketFamily.Item, PacketAction.Drop)
.AddShort(itemId)
.AddInt(amount)
.AddChar((byte)dropPoint.X)
.AddChar((byte)dropPoint.Y)
.Build();
_packetSendService.SendPacket(packet);
}

public void JunkItem(IItem item)
{
var packet = new PacketBuilder(PacketFamily.Item, PacketAction.Junk)
Expand All @@ -63,6 +74,8 @@ public interface IItemActions

void UnequipItem(short itemId, bool alternateLocation);

void DropItem(short itemId, int amount, MapCoordinate dropPoint);

void JunkItem(IItem item);
}
}
8 changes: 7 additions & 1 deletion EOLib/Domain/Item/ItemStringService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;

using AutomaticTypeMapper;
using EOLib.IO.Pub;

Expand All @@ -13,6 +12,11 @@ public string GetStringForMapDisplay(EIFRecord record, int amount)
if (amount <= 0)
throw new ArgumentException("Amount must not be zero!", nameof(amount));

return GetStringForInventoryDisplay(record, amount);
}

public string GetStringForInventoryDisplay(EIFRecord record, int amount)
{
if (record.ID == 1)
return $"{amount} {record.Name}";

Expand All @@ -23,5 +27,7 @@ public string GetStringForMapDisplay(EIFRecord record, int amount)
public interface IItemStringService
{
string GetStringForMapDisplay(EIFRecord record, int amount);

string GetStringForInventoryDisplay(EIFRecord record, int amount);
}
}
4 changes: 4 additions & 0 deletions EOLib/Domain/Notifiers/IMainCharacterEventNotifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface IMainCharacterEventNotifier

void TakeItemFromMap(short id, int amountTaken);

void DropItem(short id, int amountDropped);

void JunkItem(short id, int amountRemoved);
}

Expand All @@ -23,6 +25,8 @@ public void NotifyTakeDamage(int damageTaken, int playerPercentHealth, bool isHe

public void TakeItemFromMap(short id, int amountTaken) { }

public void DropItem(short id, int amountDropped) { }

public void JunkItem(short id, int amountTaken) { }
}
}
76 changes: 0 additions & 76 deletions EOLib/Net/API/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,15 @@ namespace EOLib.Net.API

partial class PacketAPI
{
/// <summary>
/// Occurs when any player drops an item - if characterAmount == -1, this means the item was dropped by a player other than MainPlayer
/// </summary>
public event PlayerItemDropEvent OnDropItem;
public event RemoveMapItemEvent OnRemoveItemFromMap;
public event ItemChangeEvent OnItemChange;

private void _createItemMembers()
{
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.Item, PacketAction.Drop), _handleItemDrop, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.Item, PacketAction.Add), _handleItemAdd, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.Item, PacketAction.Remove), _handleItemRemove, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.Item, PacketAction.Obtain), _handleItemObtain, true);
m_client.AddPacketHandler(new FamilyActionPair(PacketFamily.Item, PacketAction.Kick), _handleItemKick, true);
//todo: handle ITEM_ACCEPT (ExpReward item type) (I think it shows the level up animation?)
}

public bool DropItem(short id, int amount, byte x = 255, byte y = 255) //255 means use character's current location
{
if (!m_client.ConnectedAndInitialized || !Initialized)
return false;

OldPacket pkt = new OldPacket(PacketFamily.Item, PacketAction.Drop);
pkt.AddShort(id);
pkt.AddInt(amount);
if (x == 255 && y == 255)
{
pkt.AddByte(x);
pkt.AddByte(y);
}
else
{
pkt.AddChar(x);
pkt.AddChar(y);
}

return m_client.SendPacket(pkt);
}

private void _handleItemDrop(OldPacket pkt)
{
if (OnDropItem == null) return;
short _id = pkt.GetShort();
int _amount = pkt.GetThree();
int characterAmount = pkt.GetInt(); //amount remaining for the character
OldMapItem item = new OldMapItem
{
ItemID = _id,
Amount = _amount,
UniqueID = pkt.GetShort(),
X = pkt.GetChar(),
Y = pkt.GetChar(),
//turn off drop protection since main player dropped it
DropTime = DateTime.Now.AddSeconds(-5),
IsNPCDrop = false,
OwningPlayerID = 0 //id of 0 means the currently logged in player owns it
};
byte characterWeight = pkt.GetChar(), characterMaxWeight = pkt.GetChar(); //character adjusted weights

OnDropItem(characterAmount, characterWeight, characterMaxWeight, item);
}

private void _handleItemAdd(OldPacket pkt)
{
if (OnDropItem == null) return;
OldMapItem item = new OldMapItem
{
ItemID = pkt.GetShort(),
UniqueID = pkt.GetShort(),
Amount = pkt.GetThree(),
X = pkt.GetChar(),
Y = pkt.GetChar(),
DropTime = DateTime.Now,
IsNPCDrop = false,
OwningPlayerID = -1 //another player dropped. drop protection says "Item protected" w/o player name
};
OnDropItem(-1, 0, 0, item);
}

private void _handleItemRemove(OldPacket pkt)
{
if (OnRemoveItemFromMap != null)
OnRemoveItemFromMap(pkt.GetShort());
}

private void _handleItemObtain(OldPacket pkt)
{
if (OnItemChange == null) return;
Expand Down
71 changes: 71 additions & 0 deletions EOLib/PacketHandlers/Items/DropItemHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Items
{
[AutoMappedType]
public class DropItemHandler : InGameOnlyPacketHandler
{
private readonly ICharacterRepository _characterRepository;
private readonly ICharacterInventoryRepository _inventoryRepository;
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly IEnumerable<IMainCharacterEventNotifier> _mainCharacterEventNotifiers;

public override PacketFamily Family => PacketFamily.Item;

public override PacketAction Action => PacketAction.Drop;

public DropItemHandler(IPlayerInfoProvider playerInfoProvider,
ICharacterRepository characterRepository,
ICharacterInventoryRepository inventoryRepository,
ICurrentMapStateRepository currentMapStateRepository,
IEnumerable<IMainCharacterEventNotifier> mainCharacterEventNotifiers)
: base(playerInfoProvider)
{
_characterRepository = characterRepository;
_inventoryRepository = inventoryRepository;
_currentMapStateRepository = currentMapStateRepository;
_mainCharacterEventNotifiers = mainCharacterEventNotifiers;
}

public override bool HandlePacket(IPacket packet)
{
var id = packet.ReadShort();
var amountDropped = packet.ReadThree();
var amountRemaining = packet.ReadInt();

var uid = packet.ReadShort();
var dropX = packet.ReadChar();
var dropY = packet.ReadChar();

var weight = packet.ReadChar();
var maxWeight = packet.ReadChar();

_inventoryRepository.ItemInventory.RemoveWhere(x => x.ItemID == id);
if (amountRemaining > 0 || id == 1)
_inventoryRepository.ItemInventory.Add(new InventoryItem(id, amountRemaining));

var stats = _characterRepository.MainCharacter.Stats;
stats = stats.WithNewStat(CharacterStat.Weight, weight)
.WithNewStat(CharacterStat.MaxWeight, maxWeight);
_characterRepository.MainCharacter = _characterRepository.MainCharacter.WithStats(stats);

var mapItem = new Item(uid, id, dropX, dropY)
.WithAmount(amountDropped)
.WithDropTime(DateTime.Now.AddSeconds(-5));
_currentMapStateRepository.MapItems.Add(mapItem);

foreach (var notifier in _mainCharacterEventNotifiers)
notifier.DropItem(id, amountDropped);

return true;
}
}
}
43 changes: 43 additions & 0 deletions EOLib/PacketHandlers/Items/OtherPlayerDropItemHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System;

namespace EOLib.PacketHandlers.Items
{
[AutoMappedType]
public class OtherPlayerDropItemHandler : InGameOnlyPacketHandler
{
private readonly ICurrentMapStateRepository _currentMapStateRepository;

public override PacketFamily Family => PacketFamily.Item;

public override PacketAction Action => PacketAction.Add;

public OtherPlayerDropItemHandler(IPlayerInfoProvider playerInfoProvider,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider)
{
_currentMapStateRepository = currentMapStateRepository;
}

public override bool HandlePacket(IPacket packet)
{
var id = packet.ReadShort();
var uid = packet.ReadShort();

var amountDropped = packet.ReadThree();
var dropX = packet.ReadChar();
var dropY = packet.ReadChar();

var mapItem = new Item(uid, id, dropX, dropY)
.WithAmount(amountDropped)
.WithDropTime(DateTime.Now);
_currentMapStateRepository.MapItems.Add(mapItem);

return true;
}
}
}
32 changes: 32 additions & 0 deletions EOLib/PacketHandlers/Items/RemoveItemFromMapHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using AutomaticTypeMapper;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Net;
using EOLib.Net.Handlers;

namespace EOLib.PacketHandlers.Items
{
[AutoMappedType]
public class RemoveItemFromMapHandler : InGameOnlyPacketHandler
{
private readonly ICurrentMapStateRepository _currentMapStateRepository;

public override PacketFamily Family => PacketFamily.Item;

public override PacketAction Action => PacketAction.Remove;

public RemoveItemFromMapHandler(IPlayerInfoProvider playerInfoProvider,
ICurrentMapStateRepository currentMapStateRepository)
: base(playerInfoProvider)
{
_currentMapStateRepository = currentMapStateRepository;
}

public override bool HandlePacket(IPacket packet)
{
var uid = packet.ReadShort();
_currentMapStateRepository.MapItems.RemoveWhere(x => x.UniqueID == uid);
return true;
}
}
}
Loading

0 comments on commit 3f6ee12

Please sign in to comment.