feature/d01-component-system #5

Merged
NotEvil merged 20 commits from feature/d01-component-system into develop 2026-04-14 00:54:17 +00:00
Owner
No description provided.
NotEvil added 20 commits 2026-04-14 00:53:51 +00:00
Add componentConfigs field (Map<ComponentType, JsonObject>) to
DataDrivenItemDefinition record. The parser now reads an optional
"components" JSON block, resolves each key via ComponentType.fromKey(),
and stores the raw JsonObject configs for later instantiation.
Add a parallel COMPONENT_HOLDERS volatile cache to DataDrivenItemRegistry,
rebuilt from raw componentConfigs every time definitions are loaded via
reload() or mergeAll(). Cleared alongside DEFINITIONS in clear().

Two accessor methods allow looking up a ComponentHolder by ItemStack
(reads tiedup_item_id NBT) or by ResourceLocation directly.
Override onEquipped(), onUnequipped(), and canUnequip() in
DataDrivenBondageItem to delegate to the item's ComponentHolder.
The canUnequip() override preserves the existing lock check from
AbstractV2BondageItem via super.canUnequip().

Add a static getComponent() helper for external code to retrieve
a typed component from any data-driven item stack.
JSON item using all 3 implemented components: lockable (lock_resistance: 200),
resistance (base: 80), and gagging (comprehension: 0.15, range: 8.0).
Replace two separate volatile fields (DEFINITIONS, COMPONENT_HOLDERS)
with a single RegistrySnapshot record swapped atomically. This prevents
race conditions where a reader thread could see new definitions paired
with stale/empty component holders between the two volatile writes.
Remove onWornTick() from IItemComponent (default method) and
ComponentHolder (aggregate method). No V2 tick caller invokes these,
so they create a broken contract. Can be re-added when a tick
mechanism is implemented.
- Remove redundant blocksUnequip() from LockableComponent since
  AbstractV2BondageItem.canUnequip() already checks ILockable.isLocked()
- Add DataDrivenBondageItem.getItemLockResistance(ItemStack) that reads
  the per-item lock resistance from the LockableComponent, falling back
  to the global config value when absent
- Deep-copy JsonObject configs via deepCopy() before storing in the
  definition to prevent external mutation of the parsed JSON tree
- Log a warning when a component config value is not a JsonObject,
  making misconfigured JSON easier to diagnose
- LockableComponent: lock_resistance clamped to >= 0
- ResistanceComponent: base resistance clamped to >= 0
- GaggingComponent: comprehension clamped to [0.0, 1.0], range to >= 0.0

Prevents nonsensical negative values from malformed JSON configs.
Add compact constructor to DataDrivenItemDefinition that defaults null
componentConfigs to Map.of(). This makes the field guaranteed non-null,
allowing removal of null checks in hasComponent() and
DataDrivenItemRegistry.buildComponentHolders().
Replace linear values() scan with a static unmodifiable HashMap lookup.
While only 3 entries currently exist, this establishes the correct
pattern for when more component types are added.
Documents the 8 available gameplay components (lockable, resistance,
gagging, blinding, shock, gps, choking, adjustable) with config fields,
examples (GPS shock collar, adjustable blindfold), and usage tips.
NotEvil merged commit fa4c332a10 into develop 2026-04-14 00:54:17 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NotEvil/TiedUp-#5