NotEvil
c0c53f9504
feat(validation): add GlbValidator — structural validation from JSON chunk
2026-04-17 04:06:33 +02:00
NotEvil
eb759fefff
feat(validation): add diagnostic data model — GlbDiagnostic, GlbValidationResult, GlbDiagnosticRegistry
2026-04-17 04:06:33 +02:00
NotEvil
8af58b5dd5
feat(gltf): accept custom bones — remove 11-bone filter, simplify joint remap
2026-04-17 04:06:33 +02:00
NotEvil
d7f8bf6c72
fix(gltf): strip armature prefix from bone names in FurnitureGlbParser
...
Strip pipe-delimited armature prefixes (e.g., "MyRig|body" -> "body")
from bone names in parseSeatSkeleton and remapSeatAnimations, matching
the existing stripping already present in GlbParser. Without this,
isKnownBone checks fail when Blender exports prefixed bone names.
2026-04-17 04:06:33 +02:00
NotEvil
6dad447c05
fix(gltf): select mesh by 'Item' name convention with fallback
2026-04-17 04:06:33 +02:00
NotEvil
7ef85b4e92
feat(datadriven): make animation_bones optional — absent means permissive
2026-04-17 04:06:33 +02:00
NotEvil
ad74d320be
feat(gltf): add suggestBoneName + knownBoneNames helpers to GltfBoneMapper
2026-04-17 04:06:33 +02:00
5788f39d9f
Merge pull request 'refactor/god-class-decomposition' ( #17 ) from refactor/god-class-decomposition into develop
...
Reviewed-on: #17
2026-04-16 12:38:55 +00:00
NotEvil
27c86bc831
fix ghost LaborRecord entries for non-working prisoners on escape
2026-04-16 14:36:45 +02:00
NotEvil
f4aa5ffdc5
split PrisonerService + decompose EntityKidnapper
...
PrisonerService 1057L -> 474L lifecycle + 616L EscapeMonitorService
EntityKidnapper 2035L -> 1727L via LootManager, Dialogue, CaptivePriority extraction
2026-04-16 14:08:52 +02:00
ea14fc2cec
Merge pull request 'centralize all ModConfig.SERVER reads through SettingsAccessor' ( #16 ) from chore/audit-c02-config-unification into develop
...
Reviewed-on: #16
2026-04-16 11:49:22 +00:00
NotEvil
4e136cff96
centralize all ModConfig.SERVER reads through SettingsAccessor
...
No more direct ModConfig.SERVER access outside SettingsAccessor.
32 new accessor methods, 21 consumer files rerouted.
2026-04-16 13:16:05 +02:00
683eeec11f
Merge pull request 'fix/swarm-review-p0-p1-p2' ( #15 ) from fix/swarm-review-p0-p1-p2 into develop
...
Reviewed-on: #15
2026-04-16 10:37:05 +00:00
NotEvil
fd60086322
feat(i18n): complete migration — items, entities, AI goals, GUI screens
...
119 new translation keys across 3 domains:
- Items/Blocks/Misc (46 keys): tooltips, action messages, trap states
- Entities/AI Goals (55 keys): NPC speech, maid/master/guard messages
- Client GUI (18 keys): widget labels, screen buttons, merchant display
Remaining 119 Component.literal() are all intentional:
- Debug/Admin/Command wands (47) — dev tools, not player-facing
- Entity display names (~25) — dynamic getNpcName() calls
- Empty string roots (~15) — .append() chain bases
- User-typed text (~10) — /me, /pm, /norp chat content
- Runtime data (~12) — StringBuilder, gag muffling, MCA compat
2026-04-16 12:33:13 +02:00
NotEvil
9b2c5dec8e
chore(P2): V1 zombie comments cleanup + i18n events/network/items
...
Zombie comments (14 files):
- Replace references to deleted V1 classes (ItemBind, ItemCollar, IBondageItem,
BindVariant, etc.) with V2 equivalents or past-tense historical notes
- "V1 path" → "legacy slot-index path" for still-active legacy codepaths
- Clean misleading javadoc that implied V1 code was still present
i18n (13 files, 31 new keys):
- Events: 12 Component.literal() → translatable (labor tools, gag eat,
death escape, debt, punishment, grace, camp protection, chest, maid)
- Network: 12 Component.literal() → translatable (trader messages,
lockpick jam, slave freedom warnings)
- Items: 2 Component.literal() → translatable (ItemOwnerTarget tooltips)
2026-04-16 11:20:17 +02:00
NotEvil
371a138b71
fix(P1+P2): swarm review — UX fixes + V1 dead code cleanup
...
P1 — UX visible:
- Add 4 missing translations (leather_mittens, ball_gag_3d, taser, debug_wand)
- Fix earplugs resistance bucket: "blindfold" → "earplug"
- Split mixin config: core (require=1) + compat MCA (require=0)
- Bump PROTOCOL_VERSION from "1" to "2"
- Add debug_wand item model (no texture — debug only)
- Fix 3 display_name inconsistencies (chain, vine_seed, shock_collar_auto)
P2 — Dead code cleanup:
- Delete IHas3DModelConfig + Model3DConfig (zero imports)
- Remove MovementStyleResolver.resolveV1Fallback() + V1Fallback record + V1 constants
- Remove AnimationTickHandler V1 fallback block + buildAnimationId()
- Document PlayerEquipment.equipInRegion() bypass as intentional (force-equip paths)
2026-04-16 10:58:44 +02:00
NotEvil
d75b74f9f9
fix(P0): 3 exploit fixes from swarm review
...
- RISK-006: Mittens bypass lock/unlock — add HANDS check in PacketV2SelfLock/Unlock
- RISK-002: Struggle re-roll exploit — reject-if-active in startContinuous*Session()
- RISK-003: Non-V2 locked items bypass conflict resolution — check ILockable before swap
2026-04-16 10:49:04 +02:00
bce0598059
Merge pull request 'chore/audit-uc02-roomtheme-datadriven' ( #14 ) from chore/audit-uc02-roomtheme-datadriven into develop
...
Reviewed-on: #14
2026-04-16 00:38:58 +00:00
NotEvil
6d56024c7e
fix(UC-02): LOW review items — anchored path strip + corner offset doc
...
- Use substring instead of replace for path cleanup (anchored, no double-strip risk)
- Document that corner_decorations ignores x/z offsets (by design)
2026-04-16 02:32:50 +02:00
NotEvil
8823c671d7
fix(UC-02): clean theme IDs — strip directory prefix and .json suffix
...
RISK-003: Definition IDs were "tiedup:tiedup_room_themes/oubliette.json"
instead of clean "tiedup:oubliette". Now derived from filename only.
2026-04-16 01:54:03 +02:00
NotEvil
6d9d6b4b81
fix(UC-02): arch review — furniture x/z offsets + ceiling chain fidelity
...
- Add x_offset/z_offset to PositionedBlock for multi-block furniture clusters
- Furniture items now spread across 2-3 positions (matching original Java code)
- Offsets multiplied by inward direction for correct corner orientation
- Fix has_ceiling_chain: only oubliette has ceiling chains (was true for all 6)
- Fix firstCornerSpecial: oubliette cauldron uses x/z offset +1 (inward diagonal)
- Update parser to read x_offset/z_offset (defaults to 0)
2026-04-16 01:52:31 +02:00
NotEvil
706172fb9a
fix(UC-02): QA review — crypt bottom_row + ice decorations fidelity
...
- BUG-001: CRYPT bottom_row had unreachable mossy_stone_bricks (same f variable
makes mossy_cobblestone guard trigger first). Fixed weights: 0.20/0.10/0.70
- BUG-003: ICE ceiling ice stalactites (y_offset=10) were missing from JSON
- BUG-002: ICE snow corner layers use middle value (3) as compromise since
DecorationConfig.PositionedBlock doesn't support random_property
2026-04-16 01:45:04 +02:00
NotEvil
3aaf92b788
feat(UC-02): data-driven room themes — 6 JSON + consumer migration + cleanup
...
Phase 3: Extract 6 themes into JSON (oubliette, inferno, crypt, ice, sculk, sandstone)
Phase 4: Migrate HangingCagePiece to use RoomThemeRegistry.pickRandomOrFallback()
- Move 7 shared static methods from RoomTheme into HangingCagePiece
- Replace per-enum placeDecorations() with generic DecorationConfig-based placement
Phase 5: Delete RoomTheme.java (-1368L)
2026-04-16 01:39:40 +02:00
NotEvil
69f52eacf3
feat(UC-02): data-driven room theme infrastructure (Phase 1+2)
...
- BlockPalette: weighted random block selection with condition variants
- RoomThemeDefinition: immutable record with wallBlock/floorBlock/etc convenience API
- DecorationConfig: positioned block records for theme-specific decorations
- RoomThemeRegistry: volatile atomic snapshot + pickRandom(weight-based)
- RoomThemeParser: JSON parsing with BlockStateParser + random_property expansion
- RoomThemeReloadListener: scans data/<ns>/tiedup_room_themes/*.json
- Register listener in TiedUpMod.onAddReloadListeners()
2026-04-16 01:30:51 +02:00
a4fc05b503
Merge pull request 'chore/audit-s02-s05-state-cleanup' ( #13 ) from chore/audit-s02-s05-state-cleanup into develop
...
Reviewed-on: #13
2026-04-15 14:48:42 +00:00
NotEvil
7444853840
fix(S-02): remove unused host field from PlayerMovement (review)
2026-04-15 16:48:22 +02:00
NotEvil
22d79a452b
refactor(S-02/S-05): extract PlayerMovement component + fix thread safety
...
- Extract 11 movement fields from PlayerBindState into PlayerMovement component
- Replace volatile isStruggling/struggleStartTick pair with atomic StruggleSnapshot record
- Remove 5+2 misleading synchronized keywords (different monitors, all server-thread-only)
- Update all 36 MovementStyleManager field accesses to use getMovement() getters/setters
2026-04-15 16:48:22 +02:00
70f85b58a6
Merge pull request 'chore/audit-c01-i18n' ( #12 ) from chore/audit-c01-i18n into develop
...
Reviewed-on: #12
2026-04-15 14:48:07 +00:00
NotEvil
c34bac11b0
fix(C-01): review fixes — missing keys, duplicate, GPS shock i18n
...
- Add missing keephead_enabled/disabled translation keys (BUG-001)
- Remove duplicate gui.tiedup.close key at line 403 (RISK-004)
- Fix GPS shock: use null addon + send GPS_ZONE_VIOLATION separately (RISK-001)
2026-04-15 14:08:41 +02:00
NotEvil
fa5cfb913c
feat(C-01): i18n main commands — 148 translatable keys
...
Phase 3: Migrate Component.literal() in all remaining command files.
- NPCCommand (34), CellCommand (33), SocialCommand (16), CollarCommand (25),
KeyCommand (18), BountyCommand (6), KidnapSetCommand (2), CaptivityDebugCommand (7),
InventorySubCommand (3), TestAnimSubCommand (2), MasterTestSubCommand (7), DebtSubCommand (8)
- Strip all section sign color codes, use .withStyle(ChatFormatting)
- 148 new keys in en_us.json (command.tiedup.*)
- Debug/dynamic strings intentionally kept as literal
2026-04-15 13:54:26 +02:00
NotEvil
70965c2dda
feat(C-01): i18n subcommands — 33 translatable keys
...
Phase 2: Migrate all Component.literal() in 5 subcommand files.
- BindCommands, GagCommands, BlindfoldCommands, CollarCommands, AccessoryCommands
- Strip \u00a7a section signs, use .withStyle(ChatFormatting.GREEN)
- Add 33 keys to en_us.json (command.tiedup.*)
- Shared error key: command.tiedup.error.no_state
2026-04-15 13:28:02 +02:00
NotEvil
0662739fe0
feat(C-01): i18n SystemMessageManager — 83 translatable keys
...
Phase 1: Core system message migration to Component.translatable().
- Replace getMessageTemplate() hardcoded strings with getTranslationKey() key derivation
- All send methods now use Component.translatable() with positional args
- Add 83 keys to en_us.json (msg.tiedup.system.*)
- Add sendTranslatable() convenience for external callers with string args
- Migrate 3 external getTemplate() callers (PlayerShockCollar, CellRegistryV2)
- Add resistance_suffix key for sendWithResistance()
2026-04-15 13:24:05 +02:00
ac72f6aae7
Merge pull request 'chore/quickwin-fix' ( #11 ) from chore/quickwin-fix into develop
...
Reviewed-on: #11
2026-04-15 09:22:08 +00:00
NotEvil
d3bdb026f3
fix: restore missing /tiedup tie command registration (review)
2026-04-15 11:14:28 +02:00
NotEvil
c1e1f56058
refactor: split BondageSubCommand 1207L → 5 focused files (UC-01)
...
- BindCommands.java: tie, untie (156L)
- GagCommands.java: gag, ungag (140L)
- BlindfoldCommands.java: blindfold, unblind (142L)
- CollarCommands.java: collar, takecollar, enslave, free (288L)
- AccessoryCommands.java: putearplugs, takeearplugs, putclothes,
takeclothes, fullyrestrain, adjust (469L)
- BondageSubCommand.java: thin delegator (19L)
Zero logic changes — purely mechanical code move.
2026-04-15 11:09:48 +02:00
NotEvil
f945e9449b
feat(D-01/E): quickwins — debug toggle, HumanChairHelper move, collar equip
...
Q1: Remove F9 debug toggle from GltfAnimationApplier + delete dead
GltfRenderLayer + remove keybind registration
Q2: Move HumanChairHelper from state/ to util/ — pure utility with
no state dependency. 7 import updates.
Q3: Wire NECK collar equip flow in DataDrivenBondageItem:
- Target must be tied up (V1 rule preserved)
- Distance + line-of-sight validation
- Owner added to NBT before equip via CollarHelper.addOwner()
- V2EquipmentHelper handles conflict resolution
- ModSounds.COLLAR_PUT played on success
- OwnershipComponent.onEquipped registers in CollarRegistry
2026-04-15 10:57:01 +02:00
cc0ce89de5
Merge pull request 'feature/d01-branch-e-resistance' ( #10 ) from feature/d01-branch-e-resistance into develop
...
Reviewed-on: #10
2026-04-15 01:45:58 +00:00
NotEvil
db407ee68f
fix(D-01/E): padlock resistance double-count + knife progress persist (review)
...
BUG-001: PacketV2StruggleStart only adds padlock resistance bonus on
first session (when resistance >= base). Interrupted sessions that
persisted combined resistance no longer re-add the bonus, preventing
infinite resistance inflation.
BUG-002: PacketV2LockToggle UNLOCK clears knifeCutProgress and
accessoryStruggleResistance NBT keys, preventing partial knife-cut
progress from persisting across lock/unlock cycles.
2026-04-15 03:44:12 +02:00
NotEvil
d6bb030ad7
feat(D-01/E): resistance & lock system rework (E1-E7)
...
E1: Initialize currentResistance in NBT at equip time from
ResistanceComponent — eliminates MAX-scan fallback bug
E2: BuiltInLockComponent for organic items (already committed)
E3: canStruggle refactor — new model:
- ARMS: always struggle-able (no lock gating)
- Non-ARMS: only if locked OR built-in lock
- Removed dead isItemLocked() from StruggleState + overrides
E4: canUnequip already handled by BuiltInLockComponent.blocksUnequip()
via ComponentHolder delegation
E5: Help/assist mechanic deferred (needs UI design)
E6: Removed lock resistance from ILockable (5 methods + NBT key deleted)
- GenericKnife: new knifeCutProgress NBT for cutting locks
- StruggleAccessory: accessoryStruggleResistance NBT replaces lock resistance
- PacketV2StruggleStart: uses config-based padlock resistance
- All lock/unlock packets cleaned of initializeLockResistance/clearLockResistance
E7: Fixed 3 pre-existing bugs:
- B2: DataDrivenItemRegistry.clear() synchronized on RELOAD_LOCK
- B3: V2TyingPlayerTask validates heldStack before equip (prevents duplication)
- B5: EntityKidnapperMerchant.remove() cleans playerToMerchant map (memory leak)
2026-04-15 03:23:49 +02:00
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
4a3ff438c2
Merge pull request 'feature/d01-branch-d-cleanup' ( #9 ) from feature/d01-branch-d-cleanup into develop
...
Reviewed-on: #9
2026-04-15 00:54:11 +00:00
NotEvil
4d128124e6
chore: gitignore docs/ to stop them from being tracked
2026-04-15 02:52:37 +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
a572513640
chore(D-01/D): remove dead V1 handleSelfAccessory method
2026-04-15 02:12:05 +02:00
NotEvil
dfa7024e21
fix(D-01/D): blindfold ID mismatch + dispenser V2 registration (review)
...
KidnapperTheme: fix "mask_blindfold" → "blindfold_mask" across 8 themes.
The incorrect ID produced ghost items with no definition.
DispenserBehaviors: register GenericBondageDispenseBehavior.forAnyDataDriven()
for the V2 DATA_DRIVEN_ITEM singleton. Dispatches by region from the stack's
definition. V1 per-variant registrations were deleted but V2 replacement
was missing.
2026-04-15 02:10:25 +02:00
NotEvil
9302b6ccaf
chore: remove docs from branch D tracking
2026-04-15 01:59:16 +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
fccb99ef9a
Merge pull request 'feature/d01-branch-c-migration' ( #8 ) from feature/d01-branch-c-migration into develop
...
Reviewed-on: #8
2026-04-14 22:57:05 +00:00
NotEvil
b04497b5a1
chore: remove docs from branch C (should not be tracked here)
2026-04-15 00:55:02 +02:00
NotEvil
3515c89f82
fix(D-01/C): missing sync + worldgen empty registry race (review)
...
StruggleSessionManager: add V2EquipmentHelper.sync(player) after bind
resistance update to prevent data loss on server restart during struggle
HangingCagePiece: add fallback ResourceLocation arrays for worldgen when
DataDrivenItemRegistry is empty (race with reload listener on initial
world creation). Registry-first with hardcoded fallbacks.
2026-04-15 00:26:07 +02:00