HIGH RISK-001 : secondary comparator on def.id() prevents UB on
equal-priority items — no longer depends on BodyRegionV2 enum order.
New test asserts lexicographic ordering.
HIGH RISK-002 : resetLivingAnimations restores defaultLivingAnimations
snapshot. Javadoc now warns against calling setCurrentMotionsAsDefault
anywhere in the TiedUp pipeline (would leak custom bindings into
defaults, breaking unbind). Grep confirms no call site exists today.
Polish : rename tautological null test, precise null-safety doc.
First visible bondage animation pipeline orchestrator. Consumes the
primitives added in P3-01..P3-04 + P3-09 to rebuild the livingAnimations
map of a player based on currently equipped bondage items.
Design decisions :
- IdentityHashMap dedup (armbinder covers N regions -> 1 unique stack).
Defensive even though the capability already dedupes (so we don't
depend on an upstream invariant that might regress).
- Sort by posePriority ASC so highest-priority iterates last -> wins
conflicts (Map.put last-write-wins semantics in livingAnimations).
- Option B : JSON items don't bind IDLE, let EF defaults flow through
after resetLivingAnimations() which re-pushes default motions.
- null-check on animations() : 99% of V2 legacy items lack the JSON
block and return null from the parser, must be skipped silently.
- @OnlyIn(Dist.CLIENT) at class level : ClientAnimator is client-only,
server class-loader must never touch this handler.
- Extracted testable methods (extractSortedDefinitions + applyDefinitions)
with functional callbacks (Runnable + LivingAnimationAdder + Function
resolvers). Generic <T> on extractSortedDefinitions lets tests pass
Object dummies without MC ItemStack bootstrap.
Tests (15) covering :
- rebuildBondageAnimations null-safety
- extractSortedDefinitions : empty input, null resolver result, identity
dedup (multi-region), ASC priority sort, null entries skipped
- applyDefinitions : reset-only on empty, null/empty animations skipped,
multi-binding single item, two-item conflict last-write-wins, reset
ordering before any adder, end-to-end multi-region dedup, animResolver
contract (no internal dereference)
Note : this commit provides the HANDLER. The first visible bondage
animation still requires P3-06 (hook it to PacketSyncV2Equipment +
LivingEquipmentChangeEvent) and P3-08 (updateMotion state machine) to
fully light up. Jalon = pipeline viable, not yet wired.
212 tests GREEN (197 baseline + 15 new).