Skip to content

Commit

Permalink
feature: Access to Source of Dropped/Spawned Items for Server Plugins (
Browse files Browse the repository at this point in the history
…#2390)

* chore: ♻️ WIP Add item source to spawn item logic

* fix: 🐛 Add abstract method for create item source in entities

* fix: 🐛 Change properties and logic in interfaces

* feat: ✨ Add logic for MapItemSource class in MapInstance

* docs: ✏️ Update documentation text for parameter source

* fix: ♻️ Applied necessary changes from the last review

* feat: ♻️ WIP Add logic for MapHelper

* fix: 🐛 Changed MapHelper to a singleton to maintain the reference for event subscriptions

* fix: ♻️ Apply review changes in MapHelper

---------

Co-authored-by: Bryan <[email protected]>
  • Loading branch information
blinkuz and Bryan authored Nov 2, 2024
1 parent a32f7d5 commit b62d99f
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 26 deletions.
5 changes: 3 additions & 2 deletions Intersect.Server.Core/Database/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
using Intersect.GameObjects;
using Intersect.Network.Packets.Server;
using Intersect.Server.Database.PlayerData.Players;
using Intersect.Server.Framework.Items;
using Newtonsoft.Json;

namespace Intersect.Server.Database;

public class Item
public class Item: IItem
{
[JsonIgnore][NotMapped] public double DropChance = 100;
[JsonIgnore][NotMapped] public double DropChance { get; set; } = 100;

public Item()
{
Expand Down
14 changes: 10 additions & 4 deletions Intersect.Server.Core/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using Intersect.Server.Database.PlayerData.Players;
using Intersect.Server.Entities.Combat;
using Intersect.Server.Entities.Events;
using Intersect.Server.Framework.Entities;
using Intersect.Server.Framework.Items;
using Intersect.Server.General;
using Intersect.Server.Localization;
using Intersect.Server.Maps;
Expand All @@ -21,12 +23,13 @@

namespace Intersect.Server.Entities;

public abstract partial class Entity : IDisposable
public abstract partial class Entity : IEntity
{
//Instance Values
private Guid _id = Guid.NewGuid();

public Guid MapInstanceId = Guid.Empty;

[NotMapped]
public Guid MapInstanceId { get; set; } = Guid.Empty;

[JsonProperty("MaxVitals"), NotMapped] private long[] _maxVital = new long[Enum.GetValues<Vital>().Length];

Expand Down Expand Up @@ -3056,14 +3059,17 @@ protected virtual void DropItems(Entity killer, bool sendUpdate = true)
// Spawn the actual item!
if (MapController.TryGetInstanceFromMap(MapId, MapInstanceId, out var instance))
{
instance.SpawnItem(X, Y, drop, drop.Quantity, lootOwner, sendUpdate);
var itemSource = this.AsItemSource();
instance.SpawnItem(itemSource, X, Y, drop, drop.Quantity, lootOwner, sendUpdate);
}

// Process the drop (for players this would remove it from their inventory)
OnDropItem(slot, drop);
}
}

protected abstract EntityItemSource? AsItemSource();

public bool IsDead()
{
return Dead;
Expand Down
7 changes: 7 additions & 0 deletions Intersect.Server.Core/Entities/Events/EventPageInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Intersect.GameObjects.Events;
using Intersect.Network.Packets.Server;
using Intersect.Server.Entities.Pathfinding;
using Intersect.Server.Framework;
using Intersect.Server.Framework.Items;
using Intersect.Server.Maps;
using Intersect.Server.Networking;
using Intersect.Utilities;
Expand Down Expand Up @@ -892,5 +894,10 @@ public bool ShouldDespawn(MapController map)

return false;
}

protected override EntityItemSource? AsItemSource()
{
return null;
}

}
12 changes: 12 additions & 0 deletions Intersect.Server.Core/Entities/Npc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Intersect.Server.Entities.Combat;
using Intersect.Server.Entities.Events;
using Intersect.Server.Entities.Pathfinding;
using Intersect.Server.Framework.Entities;
using Intersect.Server.Framework.Items;
using Intersect.Server.Maps;
using Intersect.Server.Networking;
using Intersect.Utilities;
Expand Down Expand Up @@ -1671,5 +1673,15 @@ public override EntityPacket EntityPacket(EntityPacket packet = null, Player for

return pkt;
}

protected override EntityItemSource? AsItemSource()
{
return new EntityItemSource
{
EntityType = GetEntityType(),
EntityReference = new WeakReference<IEntity>(this),
Id = this.Base.Id
};
}

}
28 changes: 22 additions & 6 deletions Intersect.Server.Core/Entities/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
using Intersect.Server.Database.PlayerData.Security;
using Intersect.Server.Entities.Combat;
using Intersect.Server.Entities.Events;
using Intersect.Server.Framework.Entities;
using Intersect.Server.Framework.Items;
using Intersect.Server.Localization;
using Intersect.Server.Maps;
using Intersect.Server.Networking;
Expand All @@ -35,7 +37,6 @@ public partial class Player : Entity
{
[NotMapped, JsonIgnore]
public Guid PreviousMapInstanceId = Guid.Empty;

//Online Players List
private static readonly ConcurrentDictionary<Guid, Player> OnlinePlayers = new ConcurrentDictionary<Guid, Player>();

Expand Down Expand Up @@ -2781,7 +2782,7 @@ public bool TryGiveItem(Item item, ItemHandling handler = ItemHandling.Normal, b
// Do we have any items to spawn to the map?
if (spawnAmount > 0 && MapController.TryGetInstanceFromMap(Map.Id, MapInstanceId, out var instance))
{
instance.SpawnItem(overflowTileX > -1 ? overflowTileX : X, overflowTileY > -1 ? overflowTileY : Y, item, spawnAmount, Id);
instance.SpawnItem(AsItemSource(), overflowTileX > -1 ? overflowTileX : X, overflowTileY > -1 ? overflowTileY : Y, item, spawnAmount, Id);
return spawnAmount != item.Quantity;
}

Expand Down Expand Up @@ -2820,8 +2821,21 @@ public bool TryGiveItem(Item item, ItemHandling handler = ItemHandling.Normal, b
var bankInterface = new BankInterface(this, ((IEnumerable<Item>)Bank).ToList(), new object(), null, Options.Instance.Bank.MaxSlots);
return bankOverflow && bankInterface.TryDepositItem(item, sendUpdate);
}



/// <summary>
/// Creates an item source for the player entity.
/// </summary>
/// <returns>A new <see cref="EntityItemSource"/> object.</returns>
protected override EntityItemSource? AsItemSource()
{
return new EntityItemSource
{
EntityType = GetEntityType(),
EntityReference = new WeakReference<IEntity>(this),
Id = this.Id
};
}

/// <summary>
/// Gives the player an item. NOTE: This method MAKES ZERO CHECKS to see if this is possible!
/// Use TryGiveItem where possible!
Expand Down Expand Up @@ -3135,7 +3149,7 @@ public bool TryDropItemFrom(int slotIndex, int amount)
return false;
}

mapInstance.SpawnItem(X, Y, itemInSlot, itemDescriptor.IsStackable ? amount : 1, Id);
mapInstance.SpawnItem(AsItemSource(),X, Y, itemInSlot, itemDescriptor.IsStackable ? amount : 1, Id);

itemInSlot.Quantity = Math.Max(0, itemInSlot.Quantity - amount);

Expand Down Expand Up @@ -4973,6 +4987,8 @@ public void ReturnTradeItems()
return;
}

var itemSource = AsItemSource();

foreach (var offer in Trading.Offer)
{
if (offer == null || offer.ItemId == Guid.Empty)
Expand All @@ -4982,7 +4998,7 @@ public void ReturnTradeItems()

if (!TryGiveItem(offer, -1) && MapController.TryGetInstanceFromMap(MapId, MapInstanceId, out var instance))
{
instance.SpawnItem(X, Y, offer, offer.Quantity, Id);
instance.SpawnItem(itemSource, X, Y, offer, offer.Quantity, Id);
PacketSender.SendChatMsg(this, Strings.Trading.ItemsDropped, ChatMessageType.Inventory, CustomColors.Alerts.Error);
}

Expand Down
6 changes: 6 additions & 0 deletions Intersect.Server.Core/Entities/Projectile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Intersect.Network.Packets.Server;
using Intersect.Server.Database;
using Intersect.Server.Entities.Combat;
using Intersect.Server.Framework.Items;
using Intersect.Server.Maps;
using Intersect.Utilities;
using MapAttribute = Intersect.Enums.MapAttribute;
Expand Down Expand Up @@ -654,5 +655,10 @@ public override EntityType GetEntityType()
{
return EntityType.Projectile;
}

protected override EntityItemSource? AsItemSource()
{
return null;
}

}
16 changes: 15 additions & 1 deletion Intersect.Server.Core/Entities/Resource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Intersect.Network.Packets.Server;
using Intersect.Server.Database;
using Intersect.Server.Database.PlayerData.Players;
using Intersect.Server.Framework.Entities;
using Intersect.Server.Framework.Items;
using Intersect.Server.Maps;
using Intersect.Server.Networking;
using Intersect.Utilities;
Expand Down Expand Up @@ -156,6 +158,8 @@ public void SpawnResourceItems(Entity killer)
{
selectedTile = tiles[Randomization.Next(0, tiles.Count)];
}

var itemSource = AsItemSource();

// Drop items
foreach (var item in Items)
Expand All @@ -165,14 +169,24 @@ public void SpawnResourceItems(Entity killer)
var mapId = selectedTile.GetMapId();
if (MapController.TryGetInstanceFromMap(mapId, MapInstanceId, out var mapInstance))
{
mapInstance.SpawnItem(selectedTile.GetX(), selectedTile.GetY(), item, item.Quantity, killer.Id);
mapInstance.SpawnItem(itemSource, selectedTile.GetX(), selectedTile.GetY(), item, item.Quantity, killer.Id);
}
}
}
}

Items.Clear();
}

protected override EntityItemSource? AsItemSource()
{
return new EntityItemSource
{
EntityType = GetEntityType(),
EntityReference = new WeakReference<IEntity>(this),
Id = this.Base.Id
};
}

public override void ProcessRegen()
{
Expand Down
38 changes: 26 additions & 12 deletions Intersect.Server.Core/Maps/MapInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Intersect.Server.Classes.Maps;
using MapAttribute = Intersect.Enums.MapAttribute;
using Intersect.Server.Core.MapInstancing;
using Intersect.Server.Framework.Items;
using Intersect.Server.Framework.Maps;
using Intersect.Server.Plugins.Helpers;

namespace Intersect.Server.Maps;

Expand Down Expand Up @@ -47,7 +50,7 @@ namespace Intersect.Server.Maps;
/// </para>
/// </remarks>
/// </summary>
public partial class MapInstance : IDisposable
public partial class MapInstance : IMapInstance
{
/// <summary>
/// Reference to stay consistent/easy-to-read with overworld behavior
Expand Down Expand Up @@ -78,7 +81,7 @@ public partial class MapInstance : IDisposable
/// Note that this is NOT the Instance instance identifier - that is <see cref="MapInstanceId"/>
/// </remarks>
/// </summary>
public Guid Id;
public Guid Id { get; set; }

/// <summary>
/// An ID referring to which instance this processer belongs to.
Expand All @@ -87,7 +90,7 @@ public partial class MapInstance : IDisposable
/// will be processed and fed packets by that processer.
/// </remarks>
/// </summary>
public Guid MapInstanceId;
public Guid MapInstanceId { get; set; }

/// <summary>
/// The last time the <see cref="Core.LogicService.LogicThread"/> made a call to <see cref="Update(long)"/>.
Expand Down Expand Up @@ -141,7 +144,7 @@ public partial class MapInstance : IDisposable
// Animations & Text
private MapActionMessages mActionMessages = new MapActionMessages();
private MapAnimations mMapAnimations = new MapAnimations();

public MapInstance(MapController map, Guid mapInstanceId, Player creator)
{
mMapController = map;
Expand Down Expand Up @@ -700,10 +703,9 @@ private void DespawnResources()
/// <summary>
/// Add a map item to this map.
/// </summary>
/// <param name="x">The X location of this item.</param>
/// <param name="y">The Y location of this item.</param>
/// <param name="source">The source of the item, e.g. a player who dropped it, or a monster who spawned it on death, or the map instance in which it was spawned.</param>
/// <param name="item">The <see cref="MapItem"/> to add to the map.</param>
private void AddItem(MapItem item)
private void AddItem(IItemSource? source, MapItem item)
{
AllMapItems.TryAdd(item.UniqueId, item);

Expand All @@ -713,26 +715,30 @@ private void AddItem(MapItem item)
}

TileItems[item.TileIndex]?.TryAdd(item.UniqueId, item);

MapHelper.Instance.InvokeItemAdded(source, item);
}

/// <summary>
/// Spawn an item to this map instance.
/// </summary>
/// <param name="source">The source of the item, e.g. a player who dropped it, or a monster who spawned it on death, or the map instance in which it was spawned</param>
/// <param name="x">The horizontal location of this item</param>
/// <param name="y">The vertical location of this item.</param>
/// <param name="item">The <see cref="Item"/> to spawn on the map.</param>
/// <param name="amount">The amount of times to spawn this item to the map. Set to the <see cref="Item"/> quantity, overwrites quantity if stackable!</param>
public void SpawnItem(int x, int y, Item item, int amount) => SpawnItem(x, y, item, amount, Guid.Empty);
public void SpawnItem(IItemSource? source, int x, int y, Item item, int amount) => SpawnItem(source, x, y, item, amount, Guid.Empty);

/// <summary>
/// Spawn an item to this map instance.
/// </summary>
/// <param name="source">The source of the item, e.g. a player who dropped it, or a monster who spawned it on death, or the map instance in which it was spawned</param>
/// <param name="x">The horizontal location of this item</param>
/// <param name="y">The vertical location of this item.</param>
/// <param name="item">The <see cref="Item"/> to spawn on the map.</param>
/// <param name="amount">The amount of times to spawn this item to the map. Set to the <see cref="Item"/> quantity, overwrites quantity if stackable!</param>
/// <param name="owner">The player Id that will be the temporary owner of this item.</param>
public void SpawnItem(int x, int y, Item item, int amount, Guid owner, bool sendUpdate = true)
public void SpawnItem(IItemSource? source, int x, int y, Item item, int amount, Guid owner, bool sendUpdate = true)
{
if (item == null)
{
Expand Down Expand Up @@ -792,7 +798,7 @@ public void SpawnItem(int x, int y, Item item, int amount, Guid owner, bool send
}

// Drop the new item.
AddItem(mapItem);
AddItem(source, mapItem);
if (sendUpdate)
{
PacketSender.SendMapItemUpdate(mMapController.Id, MapInstanceId, mapItem, false);
Expand Down Expand Up @@ -822,7 +828,7 @@ public void SpawnItem(int x, int y, Item item, int amount, Guid owner, bool send
return;
}

AddItem(mapItem);
AddItem(source, mapItem);
}
PacketSender.SendMapItemsToProximity(mMapController.Id, this);
}
Expand Down Expand Up @@ -924,7 +930,15 @@ private void SpawnAttributeItem(int x, int y)
{
mapItem.Quantity = 1;
}
AddItem(mapItem);

var mapItemSource = new MapItemSource
{
Id = MapInstanceId,
MapInstanceReference = new WeakReference<IMapInstance>(this),
DescriptorId = mMapController.Id,
};

AddItem(mapItemSource, mapItem);
PacketSender.SendMapItemUpdate(mMapController.Id, MapInstanceId, mapItem, false);
}
}
Expand Down
Loading

0 comments on commit b62d99f

Please sign in to comment.