diff --git a/build.gradle b/build.gradle index 68119cb..eff6a43 100644 --- a/build.gradle +++ b/build.gradle @@ -104,6 +104,7 @@ minecraft { // Mixin config arg args '-mixin.config=tiedup.mixins.json' + args '-mixin.config=tiedup-compat.mixins.json' } server { @@ -116,6 +117,7 @@ minecraft { // Mixin config arg args '-mixin.config=tiedup.mixins.json' + args '-mixin.config=tiedup-compat.mixins.json' } // Additional client instances for multiplayer testing @@ -155,6 +157,7 @@ sourceSets.main.resources { srcDir 'src/generated/resources' } mixin { add sourceSets.main, 'tiedup.refmap.json' config 'tiedup.mixins.json' + config 'tiedup-compat.mixins.json' } repositories { @@ -263,7 +266,7 @@ tasks.named('jar', Jar).configure { 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), - 'MixinConfigs' : 'tiedup.mixins.json' + 'MixinConfigs' : 'tiedup.mixins.json,tiedup-compat.mixins.json' ]) } diff --git a/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java b/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java index f9b4ebd..13d84b4 100644 --- a/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java +++ b/src/main/java/com/tiedup/remake/client/animation/tick/AnimationTickHandler.java @@ -7,16 +7,12 @@ import com.tiedup.remake.client.animation.PendingAnimationManager; import com.tiedup.remake.client.animation.context.AnimationContext; import com.tiedup.remake.client.animation.context.AnimationContextResolver; import com.tiedup.remake.client.animation.context.RegionBoneMapper; -import com.tiedup.remake.client.animation.util.AnimationIdBuilder; import com.tiedup.remake.client.events.CellHighlightHandler; import com.tiedup.remake.client.events.LeashProxyClientHandler; import com.tiedup.remake.client.gltf.GltfAnimationApplier; import com.tiedup.remake.client.state.ClothesClientCache; import com.tiedup.remake.client.state.MovementStyleClientState; import com.tiedup.remake.client.state.PetBedClientState; -import com.tiedup.remake.items.base.PoseType; -import com.tiedup.remake.v2.bondage.BindModeHelper; -import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.util.HumanChairHelper; import com.tiedup.remake.state.PlayerBindState; import com.tiedup.remake.v2.BodyRegionV2; @@ -207,28 +203,9 @@ public class AnimationTickHandler { ); // Clear V1 tracking so transition back works AnimationStateRegistry.getLastAnimId().remove(uuid); - } else { - // V1 fallback - if (GltfAnimationApplier.hasActiveState(player)) { - GltfAnimationApplier.clearV2Animation(player); - } - String animId = buildAnimationId(player, state); - String lastId = AnimationStateRegistry.getLastAnimId().get( - uuid - ); - if (!animId.equals(lastId)) { - boolean success = BondageAnimationManager.playAnimation( - player, - animId - ); - if (success) { - AnimationStateRegistry.getLastAnimId().put( - uuid, - animId - ); - } - } } + // No V2 items with GLB models — nothing to animate. + // V1 items without data-driven definitions are not animated. } else if (wasTied) { // Was tied, now free - stop all animations if (GltfAnimationApplier.hasActiveState(player)) { @@ -242,53 +219,6 @@ public class AnimationTickHandler { AnimationStateRegistry.getLastTiedState().put(uuid, isTied); } - /** - * Build animation ID from player's current state (V1 path). - */ - private static String buildAnimationId( - Player player, - PlayerBindState state - ) { - ItemStack bind = state.getEquipment(BodyRegionV2.ARMS); - PoseType poseType = PoseTypeHelper.getPoseType(bind); - - // Human chair mode: override DOG pose to HUMAN_CHAIR (straight limbs) - poseType = HumanChairHelper.resolveEffectivePose(poseType, bind); - - // Derive bound state from V2 regions (works client-side, synced via capability) - boolean armsBound = V2EquipmentHelper.isRegionOccupied( - player, - BodyRegionV2.ARMS - ); - boolean legsBound = V2EquipmentHelper.isRegionOccupied( - player, - BodyRegionV2.LEGS - ); - - // V1 fallback: if no V2 regions are set but player is tied, derive from bind mode NBT - if (!armsBound && !legsBound && BindModeHelper.isBindItem(bind)) { - armsBound = BindModeHelper.hasArmsBound(bind); - legsBound = BindModeHelper.hasLegsBound(bind); - } - - boolean isStruggling = state.isStruggling(); - boolean isSneaking = player.isCrouching(); - boolean isMoving = - player.getDeltaMovement().horizontalDistanceSqr() > 1e-6; - - // Build animation ID with sneak and movement support - return AnimationIdBuilder.build( - poseType, - armsBound, - legsBound, - null, - isStruggling, - true, - isSneaking, - isMoving - ); - } - /** * Player logout event - cleanup animation data. */ diff --git a/src/main/java/com/tiedup/remake/items/bondage3d/IHas3DModelConfig.java b/src/main/java/com/tiedup/remake/items/bondage3d/IHas3DModelConfig.java deleted file mode 100644 index 2870d57..0000000 --- a/src/main/java/com/tiedup/remake/items/bondage3d/IHas3DModelConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.tiedup.remake.items.bondage3d; - -/** - * Interface for items that have a 3D model configuration. - * Implement this to provide custom position, scale, and rotation for 3D rendering. - */ -public interface IHas3DModelConfig { - /** - * Get the 3D model configuration for rendering. - * @return The Model3DConfig with position, scale, and rotation offsets - */ - Model3DConfig getModelConfig(); -} diff --git a/src/main/java/com/tiedup/remake/items/bondage3d/Model3DConfig.java b/src/main/java/com/tiedup/remake/items/bondage3d/Model3DConfig.java deleted file mode 100644 index 791ed39..0000000 --- a/src/main/java/com/tiedup/remake/items/bondage3d/Model3DConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.tiedup.remake.items.bondage3d; - -import java.util.Set; - -/** - * Configuration immutable for a 3D item. - * Contains all parameters necessary for rendering. - */ -public record Model3DConfig( - String objPath, // "tiedup:models/obj/ball_gag/model.obj" - String texturePath, // "tiedup:models/obj/ball_gag/texture.png" (or null = use MTL) - float posOffsetX, // Horizontal offset - float posOffsetY, // Vertical offset (negative = lower) - float posOffsetZ, // Depth offset (positive = forward) - float scale, // Scale (1.0 = normal size) - float rotOffsetX, // Additional X rotation - float rotOffsetY, // Additional Y rotation - float rotOffsetZ, // Additional Z rotation - Set tintMaterials // Material names to apply color tint (e.g., "Ball") -) { - /** Config without tinting */ - public static Model3DConfig simple(String objPath, String texturePath) { - return new Model3DConfig( - objPath, - texturePath, - 0, - 0, - 0, - 1.0f, - 0, - 0, - 0, - Set.of() - ); - } - - /** Config with position/rotation but no tinting */ - public Model3DConfig( - String objPath, - String texturePath, - float posOffsetX, - float posOffsetY, - float posOffsetZ, - float scale, - float rotOffsetX, - float rotOffsetY, - float rotOffsetZ - ) { - this( - objPath, - texturePath, - posOffsetX, - posOffsetY, - posOffsetZ, - scale, - rotOffsetX, - rotOffsetY, - rotOffsetZ, - Set.of() - ); - } - - /** Check if this item supports color tinting */ - public boolean supportsTinting() { - return tintMaterials != null && !tintMaterials.isEmpty(); - } -} diff --git a/src/main/java/com/tiedup/remake/network/ModNetwork.java b/src/main/java/com/tiedup/remake/network/ModNetwork.java index f6fddfa..49db8ae 100644 --- a/src/main/java/com/tiedup/remake/network/ModNetwork.java +++ b/src/main/java/com/tiedup/remake/network/ModNetwork.java @@ -93,7 +93,7 @@ import net.minecraftforge.network.simple.SimpleChannel; */ public class ModNetwork { - private static final String PROTOCOL_VERSION = "1"; + private static final String PROTOCOL_VERSION = "2"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( diff --git a/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java b/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java index b19dae4..8cac7a5 100644 --- a/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java +++ b/src/main/java/com/tiedup/remake/state/components/PlayerEquipment.java @@ -424,7 +424,14 @@ public class PlayerEquipment { /** * Low-level equip: writes to V2 capability, calls IBondageItem lifecycle hooks, syncs. - * Uses setInRegion directly because V1 items do not implement IV2BondageItem. + * + *

INTENTIONALLY bypasses V2EquipmentManager.tryEquip() because: + *

+ *

Basic safety (isRegionOccupied, canEquip) is still checked here.

*/ private void equipInRegion(BodyRegionV2 region, ItemStack stack) { Player player = host.getPlayer(); diff --git a/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java b/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java index 1c1e2f4..88b21af 100644 --- a/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java +++ b/src/main/java/com/tiedup/remake/v2/bondage/movement/MovementStyleResolver.java @@ -1,14 +1,10 @@ package com.tiedup.remake.v2.bondage.movement; -import com.tiedup.remake.items.base.PoseType; -import com.tiedup.remake.v2.bondage.BindModeHelper; -import com.tiedup.remake.v2.bondage.PoseTypeHelper; import com.tiedup.remake.v2.BodyRegionV2; import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition; import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry; import java.util.Map; import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.Nullable; /** * Resolves the winning movement style from a player's equipped bondage items. @@ -18,32 +14,15 @@ import org.jetbrains.annotations.Nullable; * *

The winning item's {@link MovementModifier} (if present) overrides the style's * default speed/jump values. Modifiers from lower-severity items are ignored.

- * - *

V1 Compatibility (H6 fix)

- *

V1 items (ItemBind) stored in V2 capability - * do not have data-driven definitions. This resolver provides a fallback that - * maps V1 bind mode + pose type to a {@link MovementStyle} with speed values matching - * the original V1 behavior, preventing double stacking between the legacy - * {@code RestraintEffectUtils} attribute modifier and the V2 modifier.

*/ public final class MovementStyleResolver { private MovementStyleResolver() {} - // --- V1 fallback speed values --- - // V1 used ADDITION(-0.09) on base 0.10 = 0.01 effective = 10% speed - // Expressed as MULTIPLY_BASE fraction: 0.10 - private static final float V1_STANDARD_SPEED = 0.10f; - - // V1 used ADDITION(-0.10) on base 0.10 = 0.00 effective = 0% speed - // Expressed as MULTIPLY_BASE fraction: 0.0 (fully immobile) - private static final float V1_IMMOBILIZED_SPEED = 0.0f; - /** * Resolve the winning movement style from all equipped items. * - *

Checks V2 data-driven definitions first, then falls back to V1 {@link ItemBind} - * introspection for items without data-driven definitions.

+ *

Uses V2 data-driven definitions to determine movement style.

* * @param equipped map of region to ItemStack (from {@code IV2BondageEquipment.getAllEquipped()}) * @return the resolved movement, or {@link ResolvedMovement#NONE} if no styled items @@ -66,7 +45,6 @@ public final class MovementStyleResolver { ItemStack stack = entry.getValue(); if (stack.isEmpty()) continue; - // --- Try V2 data-driven definition first --- DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack); if (def != null && def.movementStyle() != null) { MovementStyle style = def.movementStyle(); @@ -90,26 +68,6 @@ public final class MovementStyleResolver { bestSeverity = severity; bestRegionOrdinal = regionOrdinal; } - continue; - } - - // --- V1 fallback: ItemBind without data-driven definition --- - V1Fallback fallback = resolveV1Fallback(stack); - if (fallback != null) { - int severity = fallback.style.getSeverity(); - int regionOrdinal = region.ordinal(); - - if ( - severity > bestSeverity || - (severity == bestSeverity && - regionOrdinal < bestRegionOrdinal) - ) { - bestStyle = fallback.style; - bestSpeed = fallback.speed; - bestJumpDisabled = fallback.jumpDisabled; - bestSeverity = severity; - bestRegionOrdinal = regionOrdinal; - } } } @@ -119,56 +77,4 @@ public final class MovementStyleResolver { return new ResolvedMovement(bestStyle, bestSpeed, bestJumpDisabled); } - - // ==================== V1 Fallback ==================== - - /** - * Attempt to derive a movement style from a V1 bind item. - * - *

Only items with legs bound produce a movement style. The mapping preserves - * the original V1 speed values:

- * - * - * @param stack the ItemStack to inspect - * @return fallback resolution, or null if the item is not a V1 bind or legs are not bound - */ - @Nullable - private static V1Fallback resolveV1Fallback(ItemStack stack) { - if (!BindModeHelper.isBindItem(stack)) { - return null; - } - - if (!BindModeHelper.hasLegsBound(stack)) { - return null; - } - - PoseType poseType = PoseTypeHelper.getPoseType(stack); - - return switch (poseType) { - case WRAP, LATEX_SACK -> new V1Fallback( - MovementStyle.SHUFFLE, - V1_IMMOBILIZED_SPEED, - true - ); - case DOG, HUMAN_CHAIR -> new V1Fallback( - MovementStyle.CRAWL, - V1_STANDARD_SPEED, - true - ); - default -> - // STANDARD, STRAITJACKET: shuffle at V1 standard speed - new V1Fallback(MovementStyle.SHUFFLE, V1_STANDARD_SPEED, true); - }; - } - - /** Internal holder for V1 fallback resolution result. */ - private record V1Fallback( - MovementStyle style, - float speed, - boolean jumpDisabled - ) {} } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index c521b8f..b615014 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -78,6 +78,9 @@ description='''${mod_description}''' [[mixins]] config="tiedup.mixins.json" +[[mixins]] +config="tiedup-compat.mixins.json" + # Features are specific properties of the game environment, that you may want to declare you require. This example declares # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't # stop your mod loading on the server for example. diff --git a/src/main/resources/assets/tiedup/lang/en_us.json b/src/main/resources/assets/tiedup/lang/en_us.json index 6c2e5a4..4d0ae87 100644 --- a/src/main/resources/assets/tiedup/lang/en_us.json +++ b/src/main/resources/assets/tiedup/lang/en_us.json @@ -963,5 +963,10 @@ "command.tiedup.debt.set": "Set %1$s's total debt to %2$s emeralds.", "command.tiedup.debt.added": "Added %1$s emeralds to %2$s's debt. Remaining: %3$s", "command.tiedup.debt.removed": "Removed %1$s emeralds from %2$s's debt. Remaining: %3$s", - "command.tiedup.debt.removed_paid": "Removed %1$s emeralds from %2$s's debt. Remaining: %3$s (PAID OFF!)" + "command.tiedup.debt.removed_paid": "Removed %1$s emeralds from %2$s's debt. Remaining: %3$s (PAID OFF!)", + + "item.tiedup.leather_mittens": "Leather Mittens", + "item.tiedup.ball_gag_3d": "Ball Gag", + "item.tiedup.taser": "Taser", + "item.tiedup.debug_wand": "Debug Wand" } diff --git a/src/main/resources/assets/tiedup/models/item/debug_wand.json b/src/main/resources/assets/tiedup/models/item/debug_wand.json new file mode 100644 index 0000000..0f00b5a --- /dev/null +++ b/src/main/resources/assets/tiedup/models/item/debug_wand.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "tiedup:item/debug_wand" + } +} diff --git a/src/main/resources/data/tiedup/tiedup_items/chain.json b/src/main/resources/data/tiedup/tiedup_items/chain.json index 1b65798..9fa55c5 100644 --- a/src/main/resources/data/tiedup/tiedup_items/chain.json +++ b/src/main/resources/data/tiedup/tiedup_items/chain.json @@ -1,6 +1,6 @@ { "type": "tiedup:bondage_item", - "display_name": "Chains", + "display_name": "Chain", "translation_key": "item.tiedup.chain", "model": "tiedup:models/gltf/v2/binds/chain.glb", "regions": [ diff --git a/src/main/resources/data/tiedup/tiedup_items/classic_earplugs.json b/src/main/resources/data/tiedup/tiedup_items/classic_earplugs.json index a9944b7..9a2f4a1 100644 --- a/src/main/resources/data/tiedup/tiedup_items/classic_earplugs.json +++ b/src/main/resources/data/tiedup/tiedup_items/classic_earplugs.json @@ -17,7 +17,7 @@ "components": { "lockable": {}, "resistance": { - "id": "blindfold" + "id": "earplug" } } } \ No newline at end of file diff --git a/src/main/resources/data/tiedup/tiedup_items/shock_collar_auto.json b/src/main/resources/data/tiedup/tiedup_items/shock_collar_auto.json index e988804..6e8d48c 100644 --- a/src/main/resources/data/tiedup/tiedup_items/shock_collar_auto.json +++ b/src/main/resources/data/tiedup/tiedup_items/shock_collar_auto.json @@ -11,7 +11,7 @@ "body" ] }, - "display_name": "Auto Shock Collar", + "display_name": "Automatic Shock Collar", "translation_key": "item.tiedup.shock_collar_auto", "model": "tiedup:models/gltf/v2/collars/shock_collar_auto.glb", "components": { diff --git a/src/main/resources/data/tiedup/tiedup_items/vine_seed.json b/src/main/resources/data/tiedup/tiedup_items/vine_seed.json index b99d817..2954f1a 100644 --- a/src/main/resources/data/tiedup/tiedup_items/vine_seed.json +++ b/src/main/resources/data/tiedup/tiedup_items/vine_seed.json @@ -1,6 +1,6 @@ { "type": "tiedup:bondage_item", - "display_name": "Vine Bind", + "display_name": "Vine Seed", "translation_key": "item.tiedup.vine_seed", "model": "tiedup:models/gltf/v2/binds/vine_seed.glb", "regions": [ diff --git a/src/main/resources/tiedup-compat.mixins.json b/src/main/resources/tiedup-compat.mixins.json new file mode 100644 index 0000000..d709a1d --- /dev/null +++ b/src/main/resources/tiedup-compat.mixins.json @@ -0,0 +1,22 @@ +{ + "required": false, + "minVersion": "0.8", + "package": "com.tiedup.remake.mixin", + "compatibilityLevel": "JAVA_17", + "refmap": "tiedup.refmap.json", + "mixins": [ + "MixinMCAVillagerInteraction", + "MixinMCAVillagerLeash", + "MixinMCAOpenAIChatAI", + "MixinMCAMessenger" + ], + "client": [ + "client/MixinVillagerEntityBaseModelMCA", + "client/MixinVillagerEntityMCAAnimated", + "client/MixinMCASpeechManager", + "client/MixinMCAPlayerExtendedModel" + ], + "injectors": { + "defaultRequire": 0 + } +} diff --git a/src/main/resources/tiedup.mixins.json b/src/main/resources/tiedup.mixins.json index 21db5d0..d974c48 100644 --- a/src/main/resources/tiedup.mixins.json +++ b/src/main/resources/tiedup.mixins.json @@ -6,22 +6,14 @@ "refmap": "tiedup.refmap.json", "mixins": [ "MixinServerPlayer", - "MixinMCAVillagerInteraction", - "MixinMCAVillagerLeash", - "MixinMCAOpenAIChatAI", - "MixinMCAMessenger", "MixinLivingEntityBodyRot" ], "client": [ - "client/MixinVillagerEntityBaseModelMCA", - "client/MixinVillagerEntityMCAAnimated", - "client/MixinMCASpeechManager", - "client/MixinMCAPlayerExtendedModel", "client/MixinPlayerModel", "client/MixinCamera", "client/MixinLivingEntitySleeping" ], "injectors": { - "defaultRequire": 0 + "defaultRequire": 1 } }