feat(items): port retail shared cooldown overlays

Preserve public shared-cooldown metadata, resolve the authoritative cooldown enchantment with retail expiry semantics, and project the exact ten DAT-authored radial steps through the shared retained item-slot architecture.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-23 10:41:16 +02:00
parent 19e8863f4e
commit 6b1ae4fb76
27 changed files with 875 additions and 20 deletions

View file

@ -212,6 +212,22 @@ public sealed class ClientObjectTableTests
Assert.Equal("desc", item.Properties.Strings[100]);
}
[Fact]
public void UpdateProperties_projects_assessed_shared_cooldown_metadata()
{
var repo = new ClientObjectTable();
var item = MakeItem(100);
repo.AddOrUpdate(item);
var patch = new PropertyBundle();
patch.Ints[ClientObjectTable.SharedCooldownPropertyId] = 42;
patch.Floats[ClientObjectTable.CooldownDurationPropertyId] = 30d;
repo.UpdateProperties(100, patch);
Assert.Equal(42u, item.CooldownId);
Assert.Equal(30d, item.CooldownDuration);
}
[Fact]
public void Clear_RemovesAllItems()
{

View file

@ -0,0 +1,22 @@
using AcDream.Core.Items;
namespace AcDream.Core.Tests.Items;
public sealed class ItemCooldownDisplayTests
{
[Theory]
[InlineData(10.0, 10.0, 10)]
[InlineData(10.0, 9.0, 10)]
[InlineData(10.0, 8.999, 9)]
[InlineData(10.0, 5.0, 6)]
[InlineData(10.0, 0.001, 1)]
[InlineData(10.0, 0.0, 0)]
[InlineData(0.0, 5.0, 0)]
public void GetOverlayStep_matches_retail_truncation(
double duration,
double remaining,
int expected)
=> Assert.Equal(
expected,
ItemCooldownDisplay.GetOverlayStep(duration, remaining));
}