Commit Graph

19 Commits

Author SHA1 Message Date
NotEvil
199bf00aef feat(D-01/E): BuiltInLockComponent for organic items (E2)
- New BuiltInLockComponent: blocksUnequip() returns true (permanent lock)
- ComponentType: add BUILT_IN_LOCK enum value
- 8 organic item JSONs updated (slime, vine, web, tape variants)
- DataDrivenBondageItem: add hasBuiltInLock() static helper
2026-04-15 03:11:15 +02:00
NotEvil
3df979ceee fix(D-01/D): checkup cleanup — 5 issues resolved
1. LockableComponent: remove duplicate "Lockable" tooltip line
   (ILockable.appendLockTooltip already handles lock status display)
2. ILockable/IHasResistance Javadoc: update @link refs from deleted
   V1 classes to V2 AbstractV2BondageItem/DataDrivenBondageItem
3. SettingsAccessor Javadoc: remove stale BindVariant @link references
4. DataDrivenBondageItem: update NECK block comment (remove branch ref)
5. Delete empty bondage3d/gags/ directory
2026-04-15 02:52:27 +02:00
NotEvil
099cd0d984 feat(D-01/D): V1 cleanup — delete 28 files, ~5400 lines removed
D1: ThreadLocal alert suppression moved from ItemCollar to CollarHelper.
    onCollarRemoved() logic (kidnapper alert) moved to CollarHelper.

D2+D3: Deleted 17 V1 item classes + 4 V1-only interfaces:
  ItemBind, ItemGag, ItemBlindfold, ItemCollar, ItemEarplugs, ItemMittens,
  ItemColor, ItemClassicCollar, ItemShockCollar, ItemShockCollarAuto,
  ItemGpsCollar, ItemChokeCollar, ItemHood, ItemMedicalGag,
  IBondageItem, IHasGaggingEffect, IHasBlindingEffect, IAdjustable

D4: KidnapperTheme/KidnapperItemSelector/DispenserBehaviors migrated
    from variant enums to string-based DataDrivenItemRegistry IDs.

D5: Deleted 11 variant enums + Generic* factories + ItemBallGag3D:
  BindVariant, GagVariant, BlindfoldVariant, EarplugsVariant, MittensVariant,
  GenericBind, GenericGag, GenericBlindfold, GenericEarplugs, GenericMittens

D6: ModItems cleaned — all V1 bondage registrations removed.
D7: ModCreativeTabs rewritten — iterates DataDrivenItemRegistry.
D8+D9: All V2 helpers cleaned (V1 fallbacks removed), orphan imports removed.

Zero V1 bondage code references remain (only Javadoc comments).
All bondage items are now data-driven via 47 JSON definitions.
2026-04-15 01:55:16 +02:00
NotEvil
df56ebb6bc fix(D-01/A): adversarial review fixes — 4 logic bugs
1. NECK region explicitly blocked in interactLivingEntity() — prevents
   V2 collars equipping without ownership setup (latent, no JSONs yet)

2. Swap rollback safety: if re-equip fails after swap failure, drop the
   old bind as item entity instead of losing it silently

3. GaggingComponent: cache GagMaterial at construction time — eliminates
   valueOf() log spam on every chat message with misconfigured material

4. Dual-bind prevention: check both V1 isTiedUp() AND V2 region occupied
   in TyingInteractionHelper and PacketSelfBondage to prevent equipping
   V2 bind on top of V1 bind
2026-04-14 16:48:50 +02:00
NotEvil
eb7f06bfc8 fix(D-01/A): 3 review bugs + null guards (BUG-001, BUG-002, BUG-003, RISK-003)
BUG-001: TyingInteractionHelper swap now checks V2EquipResult — on failure,
rolls back by re-equipping the old bind instead of leaving target untied

BUG-002: OwnershipComponent.onUnequipped no longer double-calls
unregisterWearer — onCollarRemoved already handles it. Suppressed-alert
path calls unregister directly since onCollarRemoved is skipped.

BUG-003: PacketSelfBondage handleV2SelfBind now clears completed tying
task from PlayerBindState to prevent blocking future tying interactions

RISK-003: StruggleCollar get/setResistanceState null-guard on player
2026-04-14 16:38:09 +02:00
NotEvil
b79225d684 feat(D-01/A): OwnershipComponent lifecycle hooks (A7)
- onEquipped: register collar owners in CollarRegistry (server-side only)
- onUnequipped: alert kidnappers + unregister from CollarRegistry
- Guards: client-side check, ServerLevel cast, empty owners skip, try-catch
- appendTooltip: nickname, owner count, shock/GPS/choke capabilities
- Delegates alert suppression to ItemCollar.isRemovalAlertSuppressed()
2026-04-14 15:29:31 +02:00
NotEvil
751bad418d feat(D-01/A): poseType, helpers, OWNERSHIP ComponentType (A4, A5, A6)
- DataDrivenItemDefinition: add poseType field, parsed from JSON "pose_type"
- PoseTypeHelper: resolves PoseType from V2 definition or V1 ItemBind fallback
- BindModeHelper: static bind mode NBT utilities (isBindItem, hasArmsBound,
  hasLegsBound, cycleBindModeId) — works for V1 and V2 items
- CollarHelper: complete static utility class for collar operations with
  dual-path V2/V1 dispatch (ownership, features, shock, GPS, choke, alert)
- ComponentType: add OWNERSHIP enum value
- OwnershipComponent: stub class (lifecycle hooks added in next commit)
2026-04-14 15:23:08 +02:00
NotEvil
b81d3eed95 feat(D-01/A): config-driven components + tooltip hook (A1, A2, A3)
- ResistanceComponent: resistanceId delegates to SettingsAccessor at runtime,
  fallback to hardcoded base for backward compat
- GaggingComponent: material field delegates to GagMaterial enum from ModConfig,
  explicit comprehension/range overrides take priority
- IItemComponent: add default appendTooltip() method
- ComponentHolder: iterate components for tooltip contribution
- 6 components implement appendTooltip (lockable, resistance, gagging, shock,
  gps, choking)
- DataDrivenBondageItem: call holder.appendTooltip() in appendHoverText()
2026-04-14 15:05:48 +02:00
NotEvil
185ac63a44 feat(D-01): implement 5 remaining components (blinding, shock, gps, choking, adjustable) 2026-04-14 02:37:14 +02:00
NotEvil
dcc8493e5e fix(D-01): pre-built map for O(1) ComponentType.fromKey() lookup (RISK-005)
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.
2026-04-14 02:29:46 +02:00
NotEvil
3a81bb6e12 fix(D-01): clamp component config values to valid ranges (RISK-003)
- 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.
2026-04-14 02:28:42 +02:00
NotEvil
456335e0dd fix(D-01): wire LockableComponent.lockResistance via getItemLockResistance() (BUG-003)
- 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
2026-04-14 02:27:37 +02:00
NotEvil
bb209bcd8e fix(D-01): remove dead onWornTick() until V2 tick mechanism exists (BUG-002)
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.
2026-04-14 02:26:31 +02:00
NotEvil
231522c68e feat(D-01): implement GaggingComponent with comprehension and range 2026-04-14 02:01:50 +02:00
NotEvil
84f4c3a53f feat(D-01): implement ResistanceComponent, improve stack-aware resistance lookup 2026-04-14 02:01:46 +02:00
NotEvil
caeb4469b1 feat(D-01): implement LockableComponent with configurable lock resistance 2026-04-14 02:01:41 +02:00
NotEvil
1b70041c36 feat(D-01): add ComponentHolder container for item components 2026-04-14 01:38:09 +02:00
NotEvil
b8a0d839f5 feat(D-01): add ComponentType enum with stub component classes 2026-04-14 01:33:37 +02:00
NotEvil
edfc3c6506 feat(D-01): add IItemComponent interface for data-driven item behaviors 2026-04-14 01:29:24 +02:00