43f355c06b
Equipment slots reusing the AbilityRef/StatModifier machinery: EquipmentSlot [GhostField] buffer (index=slot), server-only event-driven EquipSystem (RPC). Weapon -> AbilityRef.Id swaps the attack (prefab + base stats, prediction-correct); gear -> StatModifiers tagged a reserved per-slot EquipSourceId, stripped target-agnostically via RemoveBySourceId. Item mods are INLINE on ItemDefBlob (a nested BlobArray reads empty under the by-value TryGetItem copy). Atomic equip-over swap (no item loss); DefaultAbility restores the unarmed ability on weapon-unequip. Client keys + build-safe hooks; HUD equipment panel + click-to-equip. 4 catalog weapon/gear items wired + re-baked. Play-validated host+client: weapon equip swaps AbilityRef on both worlds, gear folds into EffectiveCharacterStats, unequip reverses + restores DefaultAbility, all replicated to the owner. See DR-027. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
2.4 KiB
C#
54 lines
2.4 KiB
C#
using System.Collections.Generic;
|
|
using ProjectM.Simulation;
|
|
using UnityEngine;
|
|
|
|
namespace ProjectM.Authoring
|
|
{
|
|
/// <summary>
|
|
/// Designer-facing definition of one item (resource, tool, weapon, gear, consumable). Numeric/byte fields
|
|
/// are baked into the ItemDatabase blob (immutable, Burst-fast runtime config). Category and Tier are
|
|
/// BYTES, not enums, to dodge BOTH the MCP enum-drop hazard (manage_* silently drop enum fields when set
|
|
/// via tooling) AND the cross-assembly enum-in-Burst hazard. UI icon/description are deferred to a later
|
|
/// managed lookup keyed by id, exactly like AbilityDefinition.
|
|
/// </summary>
|
|
[CreateAssetMenu(menuName = "Project M/Item Definition", fileName = "Item_")]
|
|
public class ItemDefinition : ScriptableObject
|
|
{
|
|
[Tooltip("Stable item id (ushort range). Keep 1=Aether, 2=Ore, 3=Biomass; reserve >3 for new items; 0 = none.")]
|
|
public int ItemId = 4;
|
|
|
|
public string DisplayName = "Item";
|
|
|
|
[Tooltip("ItemCategory byte: 0=Resource, 1=Tool, 2=Weapon, 3=Gear, 4=Consumable.")]
|
|
public byte Category = ItemCategory.Resource;
|
|
|
|
[Tooltip("Progression tier (0 = base). Higher-tier tools harvest higher-tier nodes / hit harder.")]
|
|
public byte Tier = 0;
|
|
|
|
[Min(1)]
|
|
[Tooltip("Max units that stack in one inventory slot (1 for non-stacking equipment).")]
|
|
public int StackMax = 999;
|
|
|
|
[Header("Equipment (Phase 1)")]
|
|
[Tooltip("EquipSlotId byte: 0=Weapon, 1=Armor, 2=Trinket, 3=Tool, 255=not equippable.")]
|
|
public byte EquipSlot = 255;
|
|
|
|
[Tooltip("AbilityId granted when equipped in the Weapon slot (0=none): 1=Primary, 2=FastLight, 3=SlowHeavy.")]
|
|
public byte GrantedAbilityId = 0;
|
|
|
|
[Tooltip("Stat modifiers granted while equipped (first 4 used).")]
|
|
public List<ItemModAuthoring> Mods = new List<ItemModAuthoring>();
|
|
}
|
|
|
|
/// <summary>Designer-facing stat-mod grant on an equippable item; the baker writes the first 4 into ItemDefBlob's inline mod slots.</summary>
|
|
[System.Serializable]
|
|
public struct ItemModAuthoring
|
|
{
|
|
[Tooltip("StatTarget byte: 0=Damage,1=CooldownTicks,2=Range,3=ProjectileSpeed,4=AutoTargetRange,5=AutoTargetCone,6=MoveSpeed,7=TurnRate,8=MaxHealth.")]
|
|
public byte Target;
|
|
[Tooltip("ModOp byte: 0=Flat, 1=PercentAdd, 2=PercentMult.")]
|
|
public byte Op;
|
|
public float Value;
|
|
}
|
|
}
|