From 46c348105c37f6de472a29ade42b2b2066d61d44 Mon Sep 17 00:00:00 2001 From: James Hall Date: Tue, 8 Jul 2025 23:32:15 +0100 Subject: [PATCH 1/9] feat: basic superman --- .../duzo/timeless/suit/set/SetRegistry.java | 6 ++ .../timeless/suit/superman/SupermanSuit.java | 57 ++++++++++++++++++ .../superman/generic/GenericSupermanSuit.java | 39 ++++++++++++ .../suit/superman/item/SupermanSuitItem.java | 39 ++++++++++++ .../textures/suit/superman_generic.png | Bin 0 -> 1133 bytes 5 files changed, 141 insertions(+) create mode 100644 src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java create mode 100644 src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java create mode 100644 src/main/java/mc/duzo/timeless/suit/superman/item/SupermanSuitItem.java create mode 100644 src/main/resources/assets/timeless/textures/suit/superman_generic.png diff --git a/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java b/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java index 54741ebf..be584bb5 100644 --- a/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java +++ b/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java @@ -1,5 +1,7 @@ package mc.duzo.timeless.suit.set; +import mc.duzo.timeless.suit.superman.generic.GenericSupermanSuit; +import mc.duzo.timeless.suit.superman.item.SupermanSuitItem; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.minecraft.registry.Registry; @@ -28,6 +30,7 @@ public static T register(T suit) { public static SuitSet MARK_THREE; public static SuitSet MARK_TWO; public static SuitSet BATMAN_66; + public static SuitSet SUPERMAN; public static void init() { // Iron Man @@ -38,5 +41,8 @@ public static void init() { // Batman BATMAN_66 = register(new RegisteringSuitSet(new Batman66Suit(), BatmanSuitItem::new)); + + // Superman + SUPERMAN = register(new RegisteringSuitSet(new GenericSupermanSuit(), SupermanSuitItem::new)); } } diff --git a/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java new file mode 100644 index 00000000..6666750e --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java @@ -0,0 +1,57 @@ +package mc.duzo.timeless.suit.superman; + +import mc.duzo.timeless.Timeless; +import mc.duzo.timeless.datagen.provider.lang.AutomaticSuitEnglish; +import mc.duzo.timeless.power.PowerList; +import mc.duzo.timeless.suit.Suit; +import mc.duzo.timeless.suit.api.FlightSuit; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; + +public abstract class SupermanSuit extends Suit implements AutomaticSuitEnglish, FlightSuit { + private final Identifier id; + protected final PowerList powers; + + protected SupermanSuit(Identifier id, PowerList powers) { + this.id = id; + this.powers = powers; + } + + protected SupermanSuit(String mark, String modid, PowerList powers) { + this(new Identifier(modid, "superman_" + mark), powers); + } + + /** + * For Timeless heroes ONLY + * Addon mods should use other constructor + */ + protected SupermanSuit(String mark, PowerList powers) { + this(mark, Timeless.MOD_ID, powers); + } + + @Override + public PowerList getPowers() { + return powers; + } + + @Override + public boolean isBinding() { + return false; + } + + @Override + public boolean isAlwaysVisible() { + return false; + } + + @Override + public Identifier id() { + return this.id; + } + + @Override + public SoundEvent getStepSound() { + return SoundEvents.BLOCK_WOOL_STEP; + } +} diff --git a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java new file mode 100644 index 00000000..6a6c1c19 --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java @@ -0,0 +1,39 @@ +package mc.duzo.timeless.suit.superman.generic; + +import mc.duzo.timeless.power.PowerList; +import mc.duzo.timeless.power.PowerRegistry; +import mc.duzo.timeless.suit.client.ClientSuit; +import mc.duzo.timeless.suit.client.render.SuitModel; +import mc.duzo.timeless.suit.client.render.generic.SteveSuitModel; +import mc.duzo.timeless.suit.set.SetRegistry; +import mc.duzo.timeless.suit.set.SuitSet; +import mc.duzo.timeless.suit.superman.SupermanSuit; + +import java.util.function.Supplier; + +public class GenericSupermanSuit extends SupermanSuit { + + public GenericSupermanSuit() { + super("generic", PowerList.of(PowerRegistry.FLIGHT, PowerRegistry.SUPER_STRENGTH, PowerRegistry.SWIFT_SNEAK)); + } + + @Override + public SuitSet getSet() { + return SetRegistry.SUPERMAN; + } + + @Override + protected ClientSuit createClient() { + return new ClientSuit(this) { + @Override + public Supplier model() { + return () -> new SteveSuitModel(this); + } + }; + } + + @Override + public int getFlightSpeed(boolean hasBoost) { + return 50; + } +} diff --git a/src/main/java/mc/duzo/timeless/suit/superman/item/SupermanSuitItem.java b/src/main/java/mc/duzo/timeless/suit/superman/item/SupermanSuitItem.java new file mode 100644 index 00000000..2a117ebd --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/superman/item/SupermanSuitItem.java @@ -0,0 +1,39 @@ +package mc.duzo.timeless.suit.superman.item; + +import mc.duzo.timeless.core.items.SuitItem; +import mc.duzo.timeless.core.items.SuitMaterial; +import mc.duzo.timeless.datagen.provider.lang.AutomaticSuitEnglish; +import mc.duzo.timeless.datagen.provider.model.AutomaticModel; +import mc.duzo.timeless.suit.Suit; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.recipe.Ingredient; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Util; + +import java.util.EnumMap; + +public class SupermanSuitItem extends SuitItem implements AutomaticModel, AutomaticSuitEnglish { + public SupermanSuitItem(Suit suit, Type type) { + super(suit, SupermanMaterial.INSTANCE, type, new FabricItemSettings().maxCount(1)); + } + + private static class SupermanMaterial extends SuitMaterial { + public SupermanMaterial(Item repair) { + super("superman", 33, Util.make(new EnumMap(ArmorItem.Type.class), map -> { + map.put(ArmorItem.Type.BOOTS, 3); + map.put(ArmorItem.Type.LEGGINGS, 6); + map.put(ArmorItem.Type.CHESTPLATE, 8); + map.put(ArmorItem.Type.HELMET, 3); + }), 10, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 2.0F, 0.0F, () -> Ingredient.ofItems(repair)); + } + + public SupermanMaterial() { + this(Items.LEATHER); // todo + } + + public static SupermanMaterial INSTANCE = new SupermanMaterial(); + } +} diff --git a/src/main/resources/assets/timeless/textures/suit/superman_generic.png b/src/main/resources/assets/timeless/textures/suit/superman_generic.png new file mode 100644 index 0000000000000000000000000000000000000000..39899487696c833c81802cac72840b8c37149a45 GIT binary patch literal 1133 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1!2l#}zDwSN5OFq!cz|hCQP{_bw+;)EzCy#N*edG4~o^u|{B^`JcYZbrd z*?B2B>EKm+1jT-?GyZ#}>V2De5zqt%h8+yHKY)~INswRge=LAO`)2JcpaRYUkH}&M z2EM}}%y>M1MG8<*qQo_#Bsf2V7NJjy2W;+X5JPXJMfdn81 z>4(v1mNEdtZUQ?43s8lDk+A{e0*I*~9jpr=CQSjdL4XNp4ii{qkfjBX1=VF}U;vU` z-JmEOJkLS{sBVL&i(^QH``c;VlV%(6xU!n4#XT|=`1e1$x>Qx};0E8##&fq#w&px> z$g0jh<=3)%4dxDC+5Xrwtjy|?Tk+G;^jYlR>D?^m;&MLlrd+kv^!worpho&`$ zXZ#HgZM+bYwuvh#Ht^tb76Y5QNj@7dW|W=N31w&IU(d+-O=NZBiKyl|LFY6J1YS=t z^8R}zU{3_|DkTOEri6+bPKWoUwXfP4`L`aw;+(nXXvOYIfh{wNg=HpiN_@WYyxa_1?!GV0;NbXc@^wx0p{^Gny(2h3XPuDTCZ**#twmw(mXe6C4hGD< zQr2r&i(>nIKO8-hx&C)!eaw9Yg*xfa3zFpC6lpy;{m_q~M?h z)0yWp=XF*IF&=--_>NuvcVN{Gevt+3x8xd@+~s?q!EpO8!)?c0hI_0PZ-gCY|Cdb2 zWW95C;i0TG@7o!6OMj?yXn4!}>-;0@#!OUNXWMHNw(AEh zOyn()-=H@!=>|8uyWsIZHE)Cy9 cNW!c-CjIT-cZaoS{Q;$8Pgg&ebxsLQ0Ikup8vp Date: Tue, 8 Jul 2025 23:44:45 +0100 Subject: [PATCH 2/9] fix: invisible arms on superman --- .../suit/superman/generic/GenericSupermanSuit.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java index 6a6c1c19..9893d9d0 100644 --- a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java +++ b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java @@ -1,5 +1,6 @@ package mc.duzo.timeless.suit.superman.generic; +import mc.duzo.animation.generic.VisiblePart; import mc.duzo.timeless.power.PowerList; import mc.duzo.timeless.power.PowerRegistry; import mc.duzo.timeless.suit.client.ClientSuit; @@ -8,7 +9,11 @@ import mc.duzo.timeless.suit.set.SetRegistry; import mc.duzo.timeless.suit.set.SuitSet; import mc.duzo.timeless.suit.superman.SupermanSuit; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.LivingEntity; +import java.util.List; import java.util.function.Supplier; public class GenericSupermanSuit extends SupermanSuit { @@ -23,12 +28,18 @@ public SuitSet getSet() { } @Override + @Environment(EnvType.CLIENT) protected ClientSuit createClient() { return new ClientSuit(this) { @Override public Supplier model() { return () -> new SteveSuitModel(this); } + + @Override + public List getVisibleParts(LivingEntity entity) { + return List.of(VisiblePart.HEAD, VisiblePart.LEFT_ARM, VisiblePart.LEFT_SLEEVE, VisiblePart.RIGHT_ARM, VisiblePart.RIGHT_SLEEVE); + } }; } From 652ae33e8e3b1cdfcd49f734b7f5d1bfd01163a5 Mon Sep 17 00:00:00 2001 From: Loqor Date: Thu, 17 Jul 2025 18:01:56 -0500 Subject: [PATCH 3/9] merge main into superman --- src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java b/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java index b8faab72..831d1e84 100644 --- a/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java +++ b/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java @@ -1,5 +1,9 @@ package mc.duzo.timeless.suit.set; +import mc.duzo.timeless.suit.moonknight.item.MoonKnightSuitItem; +import mc.duzo.timeless.suit.moonknight.jake.JakeSuit; +import mc.duzo.timeless.suit.moonknight.marc.MarcSuit; +import mc.duzo.timeless.suit.moonknight.steven.StevenSuit; import mc.duzo.timeless.suit.superman.generic.GenericSupermanSuit; import mc.duzo.timeless.suit.superman.item.SupermanSuitItem; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; From 609f47e5e5619c7990aed35dfb71e93292173090 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 20:31:43 +0100 Subject: [PATCH 4/9] feat: superman power kit (invulnerability + super jump) extends superman's powerlist beyond the placeholder flight + super_strength + swift_sneak. now reflects superman's iconic feel: - new invulnerability power: resistance iii tick (22-tick duration refreshed every second), same pattern as super_strength - super_jump added (already existed in powerregistry, was unused on suits) heat vision / cold breath / x-ray are intentionally out of scope - those need bespoke logic (raycast / projectile / damage tuning) and deserve their own pr each. --- src/main/java/mc/duzo/timeless/power/PowerRegistry.java | 6 ++++++ .../timeless/suit/superman/generic/GenericSupermanSuit.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/mc/duzo/timeless/power/PowerRegistry.java b/src/main/java/mc/duzo/timeless/power/PowerRegistry.java index dd96e931..e6970f5f 100644 --- a/src/main/java/mc/duzo/timeless/power/PowerRegistry.java +++ b/src/main/java/mc/duzo/timeless/power/PowerRegistry.java @@ -54,6 +54,12 @@ public static T register(T entry) { }) .build().register(); public static Power SWIFT_SNEAK = Power.Builder.create(new Identifier(Timeless.MOD_ID, "swift_sneak")).build().register(); + public static Power INVULNERABILITY = Power.Builder.create(new Identifier(Timeless.MOD_ID, "invulnerability")) + .tick(player -> { + if (player.getServer().getTicks() % 20 != 0) return; + player.addStatusEffect(new StatusEffectInstance(StatusEffects.RESISTANCE, 22, 2, false, false)); + }) + .build().register(); public static void init() {} } diff --git a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java index 9893d9d0..78fdd97c 100644 --- a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java +++ b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java @@ -19,7 +19,7 @@ public class GenericSupermanSuit extends SupermanSuit { public GenericSupermanSuit() { - super("generic", PowerList.of(PowerRegistry.FLIGHT, PowerRegistry.SUPER_STRENGTH, PowerRegistry.SWIFT_SNEAK)); + super("generic", PowerList.of(PowerRegistry.FLIGHT, PowerRegistry.SUPER_STRENGTH, PowerRegistry.SUPER_JUMP, PowerRegistry.SWIFT_SNEAK, PowerRegistry.INVULNERABILITY)); } @Override From 5dbda0263f2593ed0f68e0f557fe1264ddf20ea2 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 20:56:49 +0100 Subject: [PATCH 5/9] feat: superman flight via double-tap spacebar + fix datagen pipeline double-tap activation: - new client/keybind/doubletapjumpflight detects two jump-key presses inside a 250ms window while on the ground. - on activation it resolves the player's current suit, finds the index of powerregistry.flight in the powerlist, and sends a usepowerc2spacket. flightpower toggles flightenabled, same backend as iron man's z key, just a different trigger. - ground-only gate avoids accidentally deactivating mid-flight (vertical ascent already uses repeated spacebar). datagen build pipeline: - configuredatageneration { modid = "timeless" } - without the modid filter, the animator mod's datageneratorentrypoint also fires during runDatagen and removes our generated files as "stale" since they aren't in its expected output set. only superman items hit this because they were the latest additions to the registry not yet in the cache. - sourceSets.main.resources.srcdirs += "src/main/generated" - loom 1.7's auto-include isn't firing here. explicit add lets processresources see datagen output. - processresources excludes .cache/** and uses duplicatesstrategy.include to handle the datagen pipeline's intermediate files cleanly. --- build.gradle | 19 ++++++- .../client/keybind/DoubleTapJumpFlight.java | 50 +++++++++++++++++++ .../client/keybind/TimelessKeybinds.java | 1 + 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java diff --git a/build.gradle b/build.gradle index c2e83fa1..1b589aa2 100644 --- a/build.gradle +++ b/build.gradle @@ -53,7 +53,22 @@ repositories { } fabricApi { - configureDataGeneration() + configureDataGeneration { + modId = "timeless" + } +} + +sourceSets { + main { + resources { + srcDirs += "src/main/generated" + } + } +} + +processResources { + exclude ".cache/**" + duplicatesStrategy = DuplicatesStrategy.INCLUDE } dependencies { @@ -124,3 +139,5 @@ publishing { // retrieving dependencies. } } + + diff --git a/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java b/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java new file mode 100644 index 00000000..c5a06daa --- /dev/null +++ b/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java @@ -0,0 +1,50 @@ +package mc.duzo.timeless.client.keybind; + +import java.util.Optional; + +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; + +import net.minecraft.client.network.ClientPlayerEntity; + +import mc.duzo.timeless.network.c2s.UsePowerC2SPacket; +import mc.duzo.timeless.power.PowerRegistry; +import mc.duzo.timeless.suit.Suit; + +public class DoubleTapJumpFlight { + private static final long DOUBLE_TAP_WINDOW_MS = 250; + private static long lastPressTime = 0; + private static boolean wasJumping = false; + + public static void tick(ClientPlayerEntity player) { + boolean isJumping = player.input.jumping; + boolean justPressed = isJumping && !wasJumping; + wasJumping = isJumping; + + if (!justPressed) return; + if (!player.isOnGround()) { + lastPressTime = 0; + return; + } + + long now = System.currentTimeMillis(); + if (lastPressTime != 0 && now - lastPressTime <= DOUBLE_TAP_WINDOW_MS) { + tryToggleFlight(player); + lastPressTime = 0; + } else { + lastPressTime = now; + } + } + + private static void tryToggleFlight(ClientPlayerEntity player) { + Optional maybeSuit = Suit.findSuit(player); + if (maybeSuit.isEmpty()) return; + + Suit suit = maybeSuit.get(); + if (!suit.getSet().isWearing(player)) return; + + int flightIndex = suit.getPowers().indexOf(PowerRegistry.FLIGHT); + if (flightIndex < 0) return; + + ClientPlayNetworking.send(new UsePowerC2SPacket(flightIndex + 1)); + } +} diff --git a/src/main/java/mc/duzo/timeless/client/keybind/TimelessKeybinds.java b/src/main/java/mc/duzo/timeless/client/keybind/TimelessKeybinds.java index 977f2336..ce2a355d 100644 --- a/src/main/java/mc/duzo/timeless/client/keybind/TimelessKeybinds.java +++ b/src/main/java/mc/duzo/timeless/client/keybind/TimelessKeybinds.java @@ -34,5 +34,6 @@ private static void tick(MinecraftClient client) { binds.forEach(bind -> bind.tick(player)); KeybindSync.tick(player); + DoubleTapJumpFlight.tick(player); } } From 410a589cb5efdbb27c3b150b9cdc6be1fa1a5589 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 21:01:49 +0100 Subject: [PATCH 6/9] fix: superman flight - drop ground gate, use boosted flight two issues from in-game test: 1. doubletapjumpflight required isOnGround for both presses, but pressing space on the ground jumps the player off the ground, so the second press always lands airborne -> code reset and never fired. dropped the gate. now also only activates (skip if hasFlight is already true) so mid-flight accidental double-tap will not drop the player out of the sky; z-key toggle still handles deactivation. flight search loosened to any flightpower subclass so boosted_flight is also matched. 2. superman was using plain flight (mk2/mk3 style) but the user wanted iron-man flight which is boosted_flight (mk5/mk7) - sprint while flying for the boost path. switched superman to boosted_flight. window also bumped from 250ms to 300ms which is closer to standard double-click timing. --- .../client/keybind/DoubleTapJumpFlight.java | 26 ++++++++++++------- .../superman/generic/GenericSupermanSuit.java | 2 +- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java b/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java index c5a06daa..9adeb0a0 100644 --- a/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java +++ b/src/main/java/mc/duzo/timeless/client/keybind/DoubleTapJumpFlight.java @@ -7,11 +7,13 @@ import net.minecraft.client.network.ClientPlayerEntity; import mc.duzo.timeless.network.c2s.UsePowerC2SPacket; -import mc.duzo.timeless.power.PowerRegistry; +import mc.duzo.timeless.power.Power; +import mc.duzo.timeless.power.PowerList; +import mc.duzo.timeless.power.impl.FlightPower; import mc.duzo.timeless.suit.Suit; public class DoubleTapJumpFlight { - private static final long DOUBLE_TAP_WINDOW_MS = 250; + private static final long DOUBLE_TAP_WINDOW_MS = 300; private static long lastPressTime = 0; private static boolean wasJumping = false; @@ -21,28 +23,34 @@ public static void tick(ClientPlayerEntity player) { wasJumping = isJumping; if (!justPressed) return; - if (!player.isOnGround()) { - lastPressTime = 0; - return; - } long now = System.currentTimeMillis(); if (lastPressTime != 0 && now - lastPressTime <= DOUBLE_TAP_WINDOW_MS) { - tryToggleFlight(player); + tryActivateFlight(player); lastPressTime = 0; } else { lastPressTime = now; } } - private static void tryToggleFlight(ClientPlayerEntity player) { + private static void tryActivateFlight(ClientPlayerEntity player) { + if (FlightPower.hasFlight(player)) return; + Optional maybeSuit = Suit.findSuit(player); if (maybeSuit.isEmpty()) return; Suit suit = maybeSuit.get(); if (!suit.getSet().isWearing(player)) return; - int flightIndex = suit.getPowers().indexOf(PowerRegistry.FLIGHT); + PowerList powers = suit.getPowers(); + int flightIndex = -1; + for (int i = 0; i < powers.size(); i++) { + Power p = powers.get(i); + if (p instanceof FlightPower) { + flightIndex = i; + break; + } + } if (flightIndex < 0) return; ClientPlayNetworking.send(new UsePowerC2SPacket(flightIndex + 1)); diff --git a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java index 78fdd97c..5872e604 100644 --- a/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java +++ b/src/main/java/mc/duzo/timeless/suit/superman/generic/GenericSupermanSuit.java @@ -19,7 +19,7 @@ public class GenericSupermanSuit extends SupermanSuit { public GenericSupermanSuit() { - super("generic", PowerList.of(PowerRegistry.FLIGHT, PowerRegistry.SUPER_STRENGTH, PowerRegistry.SUPER_JUMP, PowerRegistry.SWIFT_SNEAK, PowerRegistry.INVULNERABILITY)); + super("generic", PowerList.of(PowerRegistry.BOOSTED_FLIGHT, PowerRegistry.SUPER_STRENGTH, PowerRegistry.SUPER_JUMP, PowerRegistry.SWIFT_SNEAK, PowerRegistry.INVULNERABILITY)); } @Override From e7ddc2a52e28fd2865253d1a2a6c7742a0403fe0 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 21:10:02 +0100 Subject: [PATCH 7/9] fix: superman render issues from in-game test three issues, three targeted fixes: 1. real arms not matching suit translations: suitfeature called copyfrom (biped -> suit) before setangles but never copied the post-animation state back. now also calls copyto (suit -> biped) after setangles, so the player biped follows the suit's animated/rotated bones (flying tilt etc.). 2. suit not always rendering: supermansuit overrode isalwaysvisible to false, so the suit disappeared whenever the player was invisible. removed the override - default in suit.java is true, which is what we want. 3. first-person showed only the suit, no hand / no held item: the renderArm mixin was @at("HEAD") cancellable with ci.cancel(), so vanilla's player arm + sleeve + the path that lets held items reach the wrist were both stomped. switched to @at("TAIL") - vanilla draws the arm and the held-item rendering happens normally, then the suit arm is layered on top. --- .../timeless/mixin/client/PlayerEntityRendererMixin.java | 3 +-- .../mc/duzo/timeless/suit/client/render/SuitFeature.java | 1 + .../java/mc/duzo/timeless/suit/superman/SupermanSuit.java | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java b/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java index 3033245d..f13e2fd4 100644 --- a/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java +++ b/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java @@ -41,7 +41,7 @@ public PlayerEntityRendererMixin(EntityRendererFactory.Context ctx, PlayerEntity this.addFeature(new SuitFeature<>(renderer, ctx.getModelLoader())); } - @Inject(method = "renderArm" , at = @At("HEAD"), cancellable = true) + @Inject(method = "renderArm", at = @At("TAIL")) private void timeless$renderArm(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, AbstractClientPlayerEntity player, ModelPart arm, ModelPart sleeve, CallbackInfo ci){ Suit suit = Suit.findSuit(player, EquipmentSlot.CHEST).orElse(null); if (suit == null) return; @@ -56,6 +56,5 @@ public PlayerEntityRendererMixin(EntityRendererFactory.Context ctx, PlayerEntity boolean isRight = player.getMainArm() == Arm.RIGHT; this.timeless$cachedArmModel.renderArm(isRight, player, 0, matrices, vertexConsumers.getBuffer(RenderLayer.getEntityTranslucent(clientSuit.texture())), light, 1, 1, 1, 1); - ci.cancel(); } } \ No newline at end of file diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/SuitFeature.java b/src/main/java/mc/duzo/timeless/suit/client/render/SuitFeature.java index 93ce2ddb..624dc64f 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/SuitFeature.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/SuitFeature.java @@ -52,6 +52,7 @@ private void renderPart(MatrixStack matrixStack, VertexConsumerProvider vertexCo model.setVisibilityForSlot(slot); model.copyFrom(context); model.setAngles(livingEntity, f, g, j, k, l); + model.copyTo(context); model.getCape().ifPresent(cape -> { cape.visible = false; diff --git a/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java b/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java index 6666750e..290f49c2 100644 --- a/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java +++ b/src/main/java/mc/duzo/timeless/suit/superman/SupermanSuit.java @@ -40,11 +40,6 @@ public boolean isBinding() { return false; } - @Override - public boolean isAlwaysVisible() { - return false; - } - @Override public Identifier id() { return this.id; From a0d5e4eb5bada6e6d297cfb9c0f5bf3c17faf5bc Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 21:13:45 +0100 Subject: [PATCH 8/9] fix: stop suit/body z-fighting on steve+alex suit models base cuboids on stevesuitmodel and alexsuitmodel had dilation 0.0 - same dimensions as the player skin underneath - so the suit z-fought with the body wherever they overlap (whole torso, arms, legs). bumped base layer to dilation 0.25 (suit always slightly outside the player skin) and overlay layer to 0.5 (always slightly outside the new base) so the layering is body < suit-base < suit-overlay with clear depth separation. matches the convention vanilla uses for armor models. bonus: revert from previous commit was that supermansuit's isalwaysvisible removal still applies; that was a separate visibility-during-invisibility issue, not the z-fight one. --- .../client/render/generic/AlexSuitModel.java | 22 +++++++++---------- .../client/render/generic/SteveSuitModel.java | 22 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java b/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java index d1b1af60..39271c1d 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java @@ -46,23 +46,23 @@ public AlexSuitModel(ClientSuit suit) { public static TexturedModelData getTexturedModelData() { ModelData modelData = new ModelData(); ModelPartData modelPartData = modelData.getRoot(); - ModelPartData head = modelPartData.addChild("head", ModelPartBuilder.create().uv(0, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.0F)) + ModelPartData head = modelPartData.addChild("head", ModelPartBuilder.create().uv(0, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.25F)) .uv(32, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.5F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); - ModelPartData body = modelPartData.addChild("body", ModelPartBuilder.create().uv(16, 16).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(16, 32).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); + ModelPartData body = modelPartData.addChild("body", ModelPartBuilder.create().uv(16, 16).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(16, 32).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); - ModelPartData right_arm = modelPartData.addChild("right_arm", ModelPartBuilder.create().uv(40, 16).cuboid(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(40, 32).cuboid(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(-5.0F, 2.0F, 0.0F)); + ModelPartData right_arm = modelPartData.addChild("right_arm", ModelPartBuilder.create().uv(40, 16).cuboid(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(40, 32).cuboid(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(-5.0F, 2.0F, 0.0F)); - ModelPartData left_arm = modelPartData.addChild("left_arm", ModelPartBuilder.create().uv(32, 48).cuboid(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(48, 48).cuboid(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(5.0F, 2.0F, 0.0F)); + ModelPartData left_arm = modelPartData.addChild("left_arm", ModelPartBuilder.create().uv(32, 48).cuboid(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(48, 48).cuboid(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(5.0F, 2.0F, 0.0F)); - ModelPartData right_leg = modelPartData.addChild("right_leg", ModelPartBuilder.create().uv(0, 16).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(0, 32).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(-1.9F, 12.0F, 0.0F)); + ModelPartData right_leg = modelPartData.addChild("right_leg", ModelPartBuilder.create().uv(0, 16).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(0, 32).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(-1.9F, 12.0F, 0.0F)); - ModelPartData left_leg = modelPartData.addChild("left_leg", ModelPartBuilder.create().uv(16, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(0, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(1.9F, 12.0F, 0.0F)); + ModelPartData left_leg = modelPartData.addChild("left_leg", ModelPartBuilder.create().uv(16, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(0, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(1.9F, 12.0F, 0.0F)); return TexturedModelData.of(modelData, 64, 64); } diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java b/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java index 8c54ade4..3053e903 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java @@ -46,23 +46,23 @@ public SteveSuitModel(ClientSuit suit) { public static TexturedModelData getTexturedModelData() { ModelData modelData = new ModelData(); ModelPartData modelPartData = modelData.getRoot(); - ModelPartData head = modelPartData.addChild("head", ModelPartBuilder.create().uv(0, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.0F)) + ModelPartData head = modelPartData.addChild("head", ModelPartBuilder.create().uv(0, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.25F)) .uv(32, 0).cuboid(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new Dilation(0.5F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); - ModelPartData body = modelPartData.addChild("body", ModelPartBuilder.create().uv(16, 16).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(16, 32).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); + ModelPartData body = modelPartData.addChild("body", ModelPartBuilder.create().uv(16, 16).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(16, 32).cuboid(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(0.0F, 0.0F, 0.0F)); - ModelPartData right_arm = modelPartData.addChild("right_arm", ModelPartBuilder.create().uv(40, 16).cuboid(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(40, 32).cuboid(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(-5.0F, 2.0F, 0.0F)); + ModelPartData right_arm = modelPartData.addChild("right_arm", ModelPartBuilder.create().uv(40, 16).cuboid(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(40, 32).cuboid(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(-5.0F, 2.0F, 0.0F)); - ModelPartData left_arm = modelPartData.addChild("left_arm", ModelPartBuilder.create().uv(32, 48).cuboid(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(48, 48).cuboid(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(5.0F, 2.0F, 0.0F)); + ModelPartData left_arm = modelPartData.addChild("left_arm", ModelPartBuilder.create().uv(32, 48).cuboid(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(48, 48).cuboid(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(5.0F, 2.0F, 0.0F)); - ModelPartData right_leg = modelPartData.addChild("right_leg", ModelPartBuilder.create().uv(0, 16).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(0, 32).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(-1.9F, 12.0F, 0.0F)); + ModelPartData right_leg = modelPartData.addChild("right_leg", ModelPartBuilder.create().uv(0, 16).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(0, 32).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(-1.9F, 12.0F, 0.0F)); - ModelPartData left_leg = modelPartData.addChild("left_leg", ModelPartBuilder.create().uv(16, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.0F)) - .uv(0, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)), ModelTransform.pivot(1.9F, 12.0F, 0.0F)); + ModelPartData left_leg = modelPartData.addChild("left_leg", ModelPartBuilder.create().uv(16, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.25F)) + .uv(0, 48).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new Dilation(0.5F)), ModelTransform.pivot(1.9F, 12.0F, 0.0F)); return TexturedModelData.of(modelData, 64, 64); } From ab50a484bb9f6dde456ba2ee75dc2c2373d2a6e0 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 2 May 2026 21:27:17 +0100 Subject: [PATCH 9/9] fix: run flight tilt during setangles so the player biped follows it rotateParts (the procedural flight tilt + roll on body/limbs) was being called inside each suit model's render() method. but suitfeature already does: copyfrom(biped) -> suit takes biped pose setangles(...) -> suit runs animations copyto(biped) -> player biped takes suit pose model.render() -> rotateparts ran here, too late so the tilt landed on the suit only. the player's actual biped (which the suit visually overlays) kept its un-tilted pose, leaving a visible mismatch in flight. centralized the timing: suitmodel.setangles now calls a protected rotateparts hook (default no-op) right after runanimations, gated on the same anim/transform condition the subclasses used. moved the actual implementations from private to @override protected in stevesuitmodel, alexsuitmodel, genericironmanmodel, markfivemodel and removed the rotateparts call from each render(). the per-model translates/scales that lived alongside rotateparts in render() stay where they were (those are render-only matrix ops, not part-state mutations). --- .../duzo/timeless/suit/client/render/SuitModel.java | 13 +++++++++++++ .../suit/client/render/generic/AlexSuitModel.java | 10 ++-------- .../suit/client/render/generic/SteveSuitModel.java | 10 ++-------- .../suit/ironman/client/GenericIronManModel.java | 10 +++------- .../suit/ironman/mk5/client/MarkFiveModel.java | 4 ++-- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/SuitModel.java b/src/main/java/mc/duzo/timeless/suit/client/render/SuitModel.java index 21f05faf..c7ccdb0a 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/SuitModel.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/SuitModel.java @@ -44,6 +44,19 @@ public void render(MatrixStack matrices, VertexConsumer vertices, int light, int public void setAngles(LivingEntity entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) { if (!(entity instanceof AbstractClientPlayerEntity player)) return; this.runAnimations(player, animationProgress); + + SuitAnimationHolder anim = this.getAnimation(player).orElse(null); + if (anim == null || anim.getInfo().transform() == AnimationInfo.Transform.TARGETED) { + this.rotateParts(player); + } + } + + /** + * Override to apply per-frame procedural rotations (e.g. flight tilt). + * Runs from setAngles, before SuitFeature copies the suit pose back to the player biped, + * so any rotations applied here propagate to the player model too. + */ + protected void rotateParts(AbstractClientPlayerEntity player) { } protected void runAnimations(AbstractClientPlayerEntity player, float animationProgress) { diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java b/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java index 39271c1d..9abb8b39 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java @@ -73,13 +73,6 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180f)); } - if (entity instanceof AbstractClientPlayerEntity player) { - SuitAnimationHolder anim = this.getAnimation(player).orElse(null); - if (anim == null || anim.getInfo().transform() == AnimationInfo.Transform.TARGETED) { - this.rotateParts(player); - } - } - this.getPart().render(matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV, r, g, b, alpha); matrices.pop(); } @@ -109,7 +102,8 @@ private void renderLeftArm(AbstractClientPlayerEntity player, int i, MatrixStack matrices.pop(); } - private void rotateParts(AbstractClientPlayerEntity entity) { + @Override + protected void rotateParts(AbstractClientPlayerEntity entity) { if (!FlightPower.isFlying(entity)) return; Vec3d velocity = entity.getVelocity().rotateY(((float) Math.toRadians(entity.getYaw()))); diff --git a/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java b/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java index 3053e903..82113bdf 100644 --- a/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java +++ b/src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java @@ -73,13 +73,6 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180f)); } - if (entity instanceof AbstractClientPlayerEntity player) { - SuitAnimationHolder anim = this.getAnimation(player).orElse(null); - if (anim == null || anim.getInfo().transform() == AnimationInfo.Transform.TARGETED) { - this.rotateParts(player); - } - } - this.getPart().render(matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV, r, g, b, alpha); matrices.pop(); } @@ -109,7 +102,8 @@ private void renderLeftArm(AbstractClientPlayerEntity player, int i, MatrixStack matrices.pop(); } - private void rotateParts(AbstractClientPlayerEntity entity) { + @Override + protected void rotateParts(AbstractClientPlayerEntity entity) { if (!FlightPower.isFlying(entity)) return; Vec3d velocity = entity.getVelocity().rotateY(((float) Math.toRadians(entity.getYaw()))); diff --git a/src/main/java/mc/duzo/timeless/suit/ironman/client/GenericIronManModel.java b/src/main/java/mc/duzo/timeless/suit/ironman/client/GenericIronManModel.java index c45337bc..de2be618 100644 --- a/src/main/java/mc/duzo/timeless/suit/ironman/client/GenericIronManModel.java +++ b/src/main/java/mc/duzo/timeless/suit/ironman/client/GenericIronManModel.java @@ -302,12 +302,7 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V float pivotFix = -22F; - if (entity instanceof AbstractClientPlayerEntity player) { - SuitAnimationHolder anim = this.getAnimation(player).orElse(null); - if (anim == null || anim.getInfo().transform() == AnimationInfo.Transform.TARGETED) { - this.rotateParts(player); - } - + if (entity instanceof AbstractClientPlayerEntity) { pivotFix = 2F; matrices.translate(0f, -1.5125f, 0f); matrices.scale(1.01f, 1.01f, 1.01f); @@ -322,7 +317,8 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V matrices.pop(); } - private void rotateParts(AbstractClientPlayerEntity entity) { + @Override + protected void rotateParts(AbstractClientPlayerEntity entity) { if (!FlightPower.isFlying(entity)) return; Vec3d velocity = entity.getVelocity().rotateY(((float) Math.toRadians(entity.getYaw()))); diff --git a/src/main/java/mc/duzo/timeless/suit/ironman/mk5/client/MarkFiveModel.java b/src/main/java/mc/duzo/timeless/suit/ironman/mk5/client/MarkFiveModel.java index 7205639f..fd0bd5da 100644 --- a/src/main/java/mc/duzo/timeless/suit/ironman/mk5/client/MarkFiveModel.java +++ b/src/main/java/mc/duzo/timeless/suit/ironman/mk5/client/MarkFiveModel.java @@ -294,7 +294,6 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V if (entity instanceof AbstractClientPlayerEntity player) { SuitAnimationHolder anim = this.getAnimation(player).orElse(null); if (anim == null || anim.getInfo().transform() == AnimationInfo.Transform.TARGETED) { - this.rotateParts(player); matrices.translate(0f, -0.2f, 0f); } } @@ -306,7 +305,8 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V matrices.pop(); } - private void rotateParts(AbstractClientPlayerEntity entity) { + @Override + protected void rotateParts(AbstractClientPlayerEntity entity) { if (!FlightPower.isFlying(entity)) return; Vec3d velocity = entity.getVelocity().rotateY(((float) Math.toRadians(entity.getYaw())));