Files
Project-M/Assets/_Project/Scripts/Authoring/Items/ItemDatabaseAuthoring.cs
T
kronic 4a8220ad3e LANTERN purge B6: delete the legacy single-ability path (sockets are THE ability model)
AbilityRef, AbilityCooldown, EffectiveAbilityStats, DefaultAbility deleted.
GoInGameServerSystem seeds the per-frame 4-socket Spark loadout UNCONDITIONALLY
(was gym-only); ClassSelectReceiveSystem + DebugOp.SetClass swap FrameId +
re-seed sockets + zero SocketCooldown; ClassSwapUtil.Apply drops newAbilityId;
EquipSystem weapons become stat-sticks (GrantedAbilityId removed from the item
blob/authoring); StatRecomputeSystem folds CharacterStatsRef + sockets only;
HUD cooldown bar reads socket 0 of SocketCooldown/EffectiveSocketStats; class
HUD readers are FrameId-only (ClassForAbility/AbilityFor deleted);
DebugModifierInjectionSystem drops CycleAbility.

390 tests green; Play-verified: a non-gym spawn gets frame=2 with Sparks
[7,8,6,9] and no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:47:12 -07:00

70 lines
2.9 KiB
C#

using System.Collections.Generic;
using ProjectM.Simulation;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
namespace ProjectM.Authoring
{
/// <summary>
/// Bakes the designer-authored item definitions into a single ItemDatabase blob singleton (immutable,
/// shared, Burst-fast), mirroring AbilityDatabaseAuthoring. Place ONE in the gameplay subscene; it streams
/// identically into the client and server worlds (config, not replicated). DependsOn each definition so a
/// value change re-bakes the blob. Runtime lookup is ID-keyed (ItemDatabaseBlob.TryGetItem), so the list
/// order here does not matter and inserting an item never renumbers existing ids.
/// </summary>
public class ItemDatabaseAuthoring : MonoBehaviour
{
[Tooltip("All item definitions in the game (resources + tools/gear). Looked up at runtime by ItemId.")]
public List<ItemDefinition> Items = new List<ItemDefinition>();
private class DatabaseBaker : Baker<ItemDatabaseAuthoring>
{
public override void Bake(ItemDatabaseAuthoring authoring)
{
var entity = GetEntity(TransformUsageFlags.None);
int count = authoring.Items != null ? authoring.Items.Count : 0;
var builder = new BlobBuilder(Allocator.Temp);
ref var root = ref builder.ConstructRoot<ItemDatabaseBlob>();
var arr = builder.Allocate(ref root.Items, count);
for (int i = 0; i < count; i++)
{
var def = authoring.Items[i];
if (def == null) { arr[i] = default; continue; }
DependsOn(def);
arr[i] = new ItemDefBlob
{
ItemId = (ushort)def.ItemId,
Category = def.Category,
Tier = def.Tier,
StackMax = def.StackMax,
EquipSlot = def.EquipSlot,
Mod0 = ModAt(def, 0),
Mod1 = ModAt(def, 1),
Mod2 = ModAt(def, 2),
Mod3 = ModAt(def, 3),
Name = def.DisplayName,
};
}
var blob = builder.CreateBlobAssetReference<ItemDatabaseBlob>(Allocator.Persistent);
builder.Dispose();
AddBlobAsset(ref blob, out _);
AddComponent(entity, new ItemDatabase { Value = blob });
static ItemModSpec ModAt(ItemDefinition def, int i)
{
if (def.Mods != null && i < def.Mods.Count)
{
var m = def.Mods[i];
return new ItemModSpec { Target = m.Target, Op = m.Op, Value = m.Value };
}
return new ItemModSpec { Target = 255 };
}
}
}
}
}