using Archipelago.MultiClient.Net.Models;
using ItemChanger.Modules;
using System.Collections.Generic;
namespace Archipelago.HollowKnight.IC.Modules;
public class ArchipelagoRemoteItemCounterModule : Module
{
///
/// Full history of remote items received and saved by the client. Keys are player, location, item to finally reach a count.
///
private readonly Dictionary>> savedItemCounts = new();
///
/// History of items seen when receiving from server. Keys are player, location, item to finally reach a count.
///
private readonly Dictionary>> serverSeenItemCounts = new();
public override void Initialize()
{
}
public override void Unload()
{
}
///
/// Determines whether the specified item should be received from the server based on the current counts. Should be called before receiving the item.
///
/// The item to evaluate for receiving from the server.
///
/// if receiving the item would result in the server count exceeding the local saved count;
/// otherwise, .
///
public bool ShouldReceiveServerItem(ItemInfo item)
{
int currentSavedCount = EnsureCountExists(item.Player, item.LocationId, item.ItemId, savedItemCounts);
int currentServerCount = EnsureCountExists(item.Player, item.LocationId, item.ItemId, serverSeenItemCounts);
// if obtaining this item will have sent more items from the server than we have locally, we should receive the item. otherwise we should skip it.
return currentServerCount + 1 > currentSavedCount;
}
///
/// Increments the server-side count for the specified item.
///
/// The object representing the item whose count is to be incremented. This includes details
/// such as the player, location, and item identifier.
public void IncrementServerCountForItem(ItemInfo item)
{
EnsureCountExists(item.Player, item.LocationId, item.ItemId, serverSeenItemCounts);
IncrementCurrentCountForItem(item.Player, item.LocationId, item.ItemId, serverSeenItemCounts);
}
///
/// Increments the saved count for a specific item at a given location for a specified player.
///
/// The identifier of the player for whom the item's saved count is being incremented.
/// The identifier of the location where the item is stored.
/// The identifier of the item whose saved count is being incremented.
public void IncrementSavedCountForItem(int player, long locationId, long itemId)
{
EnsureCountExists(player, locationId, itemId, savedItemCounts);
IncrementCurrentCountForItem(player, locationId, itemId, savedItemCounts);
}
private static void IncrementCurrentCountForItem(int player, long locationId, long itemId, Dictionary>> itemCounts, int incrementBy = 1)
{
itemCounts[player][locationId][itemId] += incrementBy;
}
private static int EnsureCountExists(int player, long locationId, long itemId, Dictionary>> itemCounts)
{
if (!itemCounts.TryGetValue(player, out Dictionary> a))
{
itemCounts[player] = a = new();
}
if (!a.TryGetValue(locationId, out Dictionary b))
{
a[locationId] = b = new();
}
if (!b.TryGetValue(itemId, out int count))
{
b[itemId] = count = 0;
}
return count;
}
}