From 33be4dc2ad01892d47f546650ff6555618e4d00c Mon Sep 17 00:00:00 2001 From: James Hall Date: Mon, 28 Jul 2025 16:02:54 +0100 Subject: [PATCH 1/2] refactor: first-person hand will now render if in visible parts fix: first-person hand rotations for Alex/Steve models api: BasicTogglePower feat: basic fantastic 4 suit ( placeholder texture ) --- src/main/java/mc/duzo/timeless/Timeless.java | 5 + .../client/PlayerEntityRendererMixin.java | 19 ++- .../duzo/timeless/power/BasicTogglePower.java | 67 ++++++++ .../mc/duzo/timeless/power/PowerRegistry.java | 4 + .../timeless/suit/api/SimpleSuitItem.java | 14 ++ .../timeless/suit/api/SimpleSuitMaterial.java | 21 +++ .../suit/client/render/SuitModel.java | 7 + .../client/render/generic/AlexSuitModel.java | 7 +- .../client/render/generic/SteveSuitModel.java | 5 +- .../suit/fantastic/FantasticFourSuit.java | 144 ++++++++++++++++++ .../duzo/timeless/suit/set/SetRegistry.java | 13 ++ .../timeless/textures/suit/fantastic_four.png | Bin 0 -> 1017 bytes 12 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 src/main/java/mc/duzo/timeless/power/BasicTogglePower.java create mode 100644 src/main/java/mc/duzo/timeless/suit/api/SimpleSuitItem.java create mode 100644 src/main/java/mc/duzo/timeless/suit/api/SimpleSuitMaterial.java create mode 100644 src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java create mode 100644 src/main/resources/assets/timeless/textures/suit/fantastic_four.png diff --git a/src/main/java/mc/duzo/timeless/Timeless.java b/src/main/java/mc/duzo/timeless/Timeless.java index 4d4afcc8..aab3123a 100644 --- a/src/main/java/mc/duzo/timeless/Timeless.java +++ b/src/main/java/mc/duzo/timeless/Timeless.java @@ -2,6 +2,7 @@ import dev.amble.lib.container.RegistryContainer; import net.fabricmc.api.ModInitializer; +import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,4 +39,8 @@ public void onInitialize() { // Networking Network.init(); } + + public static Identifier id(String path) { + return new Identifier(MOD_ID, path); + } } \ No newline at end of file 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 c8e5aa90..c43c9ab8 100644 --- a/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java +++ b/src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java @@ -1,5 +1,6 @@ package mc.duzo.timeless.mixin.client; +import mc.duzo.timeless.suit.client.render.SuitModel; import net.minecraft.entity.EquipmentSlot; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -35,6 +36,20 @@ public PlayerEntityRendererMixin(EntityRendererFactory.Context ctx, PlayerEntity } @Inject(method = "renderArm" , at = @At("HEAD"), cancellable = true) + private void timeless$stopArmRender(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; + ClientSuit clientSuit = suit.toClient(); + if (!(clientSuit.hasModel())) return; + + boolean isRight = player.getMainArm() == Arm.RIGHT; + // todo - this will create a new model every frame, which is bad + SuitModel model = clientSuit.model().get(); + + if (!model.shouldRenderOriginalArm(isRight, player)) ci.cancel(); + } + + @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; @@ -43,7 +58,7 @@ public PlayerEntityRendererMixin(EntityRendererFactory.Context ctx, PlayerEntity boolean isRight = player.getMainArm() == Arm.RIGHT; // todo - this will create a new model every frame, which is bad - clientSuit.model().get().renderArm(isRight, player, 0, matrices, vertexConsumers.getBuffer(RenderLayer.getEntityTranslucent(clientSuit.texture())), light, 1, 1, 1, 1); - ci.cancel(); + SuitModel model = clientSuit.model().get(); + model.renderArm(isRight, player, 0, matrices, vertexConsumers.getBuffer(RenderLayer.getEntityTranslucent(clientSuit.texture())), light, 1, 1, 1, 1); } } \ No newline at end of file diff --git a/src/main/java/mc/duzo/timeless/power/BasicTogglePower.java b/src/main/java/mc/duzo/timeless/power/BasicTogglePower.java new file mode 100644 index 00000000..9eab453c --- /dev/null +++ b/src/main/java/mc/duzo/timeless/power/BasicTogglePower.java @@ -0,0 +1,67 @@ +package mc.duzo.timeless.power; + +import mc.duzo.timeless.suit.api.EquipSoundSupplier; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.function.Consumer; + +public class BasicTogglePower extends TogglePower { + @Nullable + protected final Consumer toggleAction; + @Nullable + protected final Consumer enabledTick; + @Nullable + protected final Consumer disabledTick; + + public BasicTogglePower(String modid, String key, + @Nullable Consumer enabled, + @Nullable Consumer toggle, + @Nullable Consumer disabledTick) { + super(modid, key); + + this.toggleAction = toggle; + this.enabledTick = enabled; + this.disabledTick = disabledTick; + } + + @Override + public boolean run(ServerPlayerEntity player) { + if (toggleAction != null) { + toggleAction.accept(player); + } + + return super.run(player); + } + + @Override + public void tick(ServerPlayerEntity player) { + boolean value = getValue(player); + + if (value && enabledTick != null) { + enabledTick.accept(player); + } else if (!value && disabledTick != null) { + disabledTick.accept(player); + } + + super.tick(player); + } + + @Override + protected Class getSuitClass() { + return EquipSoundSupplier.class; + } + + @Override + public Identifier getAnimation(boolean isOpening, EquipSoundSupplier suit) { + return null; + } + + @Override + public Optional getSound(EquipSoundSupplier suit) { + return suit.getEquipSound(); + } +} diff --git a/src/main/java/mc/duzo/timeless/power/PowerRegistry.java b/src/main/java/mc/duzo/timeless/power/PowerRegistry.java index dd96e931..28a3ea3f 100644 --- a/src/main/java/mc/duzo/timeless/power/PowerRegistry.java +++ b/src/main/java/mc/duzo/timeless/power/PowerRegistry.java @@ -54,6 +54,10 @@ 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 BasicTogglePower INVISIBILITY = new BasicTogglePower(Timeless.MOD_ID, "invisibility", (player) -> { + if (player.getServer().getTicks() % 20 != 0) return; // Run every second + player.addStatusEffect(new StatusEffectInstance(StatusEffects.INVISIBILITY, 22, 3, false, false)); + }, null, null).register(); public static void init() {} } diff --git a/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitItem.java b/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitItem.java new file mode 100644 index 00000000..784a7a1b --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitItem.java @@ -0,0 +1,14 @@ +package mc.duzo.timeless.suit.api; + +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; + +public class SimpleSuitItem extends SuitItem implements AutomaticModel, AutomaticSuitEnglish { + public SimpleSuitItem(Suit suit, Type type, SuitMaterial material) { + super(suit, material, type, new FabricItemSettings().maxCount(1)); + } +} diff --git a/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitMaterial.java b/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitMaterial.java new file mode 100644 index 00000000..3d0fe868 --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/api/SimpleSuitMaterial.java @@ -0,0 +1,21 @@ +package mc.duzo.timeless.suit.api; + +import mc.duzo.timeless.core.items.SuitMaterial; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; +import net.minecraft.recipe.Ingredient; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Util; + +import java.util.EnumMap; + +public class SimpleSuitMaterial extends SuitMaterial { + public SimpleSuitMaterial(Item repair, String name) { + super(name, 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_CHAIN, 2.0F, 0.0F, () -> Ingredient.ofItems(repair)); + } +} 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..e0cef766 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 @@ -1,6 +1,7 @@ package mc.duzo.timeless.suit.client.render; import mc.duzo.animation.generic.AnimationInfo; +import mc.duzo.animation.generic.VisiblePart; import mc.duzo.timeless.suit.client.ClientSuit; import mc.duzo.timeless.suit.client.animation.SuitAnimationHolder; import mc.duzo.timeless.suit.client.animation.SuitAnimationTracker; @@ -26,6 +27,12 @@ public abstract class SuitModel extends EntityModel { public abstract void render(LivingEntity entity, float tickDelta, MatrixStack matrices, VertexConsumer vertexConsumers, int light, float r, float g, float b, float alpha); public abstract void renderArm(boolean isRight, AbstractClientPlayerEntity player, int i, MatrixStack matrices, VertexConsumer buffer, int light, int i1, int i2, int i3, int i4); + public boolean shouldRenderOriginalArm(boolean isRight, AbstractClientPlayerEntity player) { + VisiblePart requiredPart = isRight ? VisiblePart.RIGHT_ARM : VisiblePart.LEFT_ARM; + + return this.getSuit().getVisibleParts(player).contains(requiredPart); + } + /** * Sets the visibility of the model parts for the given slot. */ 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..109b3ffc 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 @@ -86,7 +86,7 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V @Override public void renderArm(boolean isRight, AbstractClientPlayerEntity player, int i, MatrixStack matrices, VertexConsumer buffer, int light, int i1, int i2, int i3, int i4) { - if (isRight) this.renderRightArm(player, i, matrices, buffer, light, i1, i2, i3, i4); + if (isRight) this.renderRightArm(player, i, matrices, buffer, light, i1, i2, i3, i4); else this.renderLeftArm(player, i, matrices, buffer, light, i1, i2, i3, i4); } @@ -94,7 +94,8 @@ private void renderRightArm(AbstractClientPlayerEntity player, int i, MatrixStac matrices.push(); this.rightArm.resetTransform(); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-0.5f)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(5f)); + matrices.translate(0.015F, -0.015F, -0.055F); this.rightArm.render(matrices, buffer, light, OverlayTexture.DEFAULT_UV, 1f, 1f, 1f, 1f); matrices.pop(); @@ -104,6 +105,8 @@ private void renderLeftArm(AbstractClientPlayerEntity player, int i, MatrixStack matrices.push(); this.leftArm.resetTransform(); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-5f)); + matrices.translate(0.015F, -0.015F, -0.055F); this.leftArm.render(matrices, buffer, light, OverlayTexture.DEFAULT_UV, 1f, 1f, 1f, 1f); matrices.pop(); 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..f8a8513c 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 @@ -94,7 +94,8 @@ private void renderRightArm(AbstractClientPlayerEntity player, int i, MatrixStac matrices.push(); this.rightArm.resetTransform(); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-0.5f)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(5f)); + matrices.translate(0.015F, -0.015F, -0.055F); this.rightArm.render(matrices, buffer, light, OverlayTexture.DEFAULT_UV, 1f, 1f, 1f, 1f); matrices.pop(); @@ -104,6 +105,8 @@ private void renderLeftArm(AbstractClientPlayerEntity player, int i, MatrixStack matrices.push(); this.leftArm.resetTransform(); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-5f)); + matrices.translate(0.015F, -0.015F, -0.055F); this.leftArm.render(matrices, buffer, light, OverlayTexture.DEFAULT_UV, 1f, 1f, 1f, 1f); matrices.pop(); diff --git a/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java b/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java new file mode 100644 index 00000000..a080c903 --- /dev/null +++ b/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java @@ -0,0 +1,144 @@ +package mc.duzo.timeless.suit.fantastic; + +import mc.duzo.animation.generic.VisibilityList; +import mc.duzo.animation.generic.VisiblePart; +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 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.SuitSet; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.LivingEntity; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.random.Random; + +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +public abstract class FantasticFourSuit extends Suit implements AutomaticSuitEnglish, FlightSuit { + private final Identifier id; + + protected FantasticFourSuit(Identifier id) { + this.id = id; + } + + protected FantasticFourSuit(String mark, String modid) { + this(new Identifier(modid, "fantastic_" + mark)); + } + + /** + * For Timeless heroes ONLY + * Addon mods should use other constructor + */ + protected FantasticFourSuit(String mark) { + this(mark, Timeless.MOD_ID); + } + + public static FantasticFourSuit create(Identifier id, PowerList powers, Supplier set) { + return new FantasticFourSuit(id) { + @Override + public PowerList getPowers() { + return powers; + } + + @Override + public SuitSet getSet() { + return set.get(); + } + + @Override + public int getFlightSpeed(boolean hasBoost) { + return 50; + } + }; + } + + @Override + public boolean isBinding() { + return true; + } + + @Override + public Identifier id() { + return this.id; + } + + @Override + public SoundEvent getStepSound() { + return SoundEvents.BLOCK_WOOL_STEP; + } + + @Override + public Optional getEquipSound() { + return Optional.of(SoundEvents.ITEM_ARMOR_EQUIP_LEATHER); + } + + @Override + public Optional getUnequipSound() { + return Optional.of(SoundEvents.ITEM_ARMOR_EQUIP_LEATHER); + } + + + @Override + public void createFlightParticles(ServerPlayerEntity player) { + // taken from the old forge archive, will need reworking + ServerWorld world = player.getServerWorld(); + Random random = world.getRandom(); + + int i = MathHelper.clamp(0, 0, 64); + double f2 = Math.cos(player.getBodyYaw() * ((float) Math.PI / 180F)) * (0.1F + 0.21F * (float) i); + double f3 = Math.sin(player.getBodyYaw() * ((float) Math.PI / 180F)) * (0.1F + 0.21F * (float) i); + double f4 = Math.cos(player.getBodyYaw() * ((float) Math.PI / 180F)) * (0.4F + 0.21F * (float) i); + double f5 = Math.sin(player.getBodyYaw() * ((float) Math.PI / 180F)) * (0.4F + 0.21F * (float) i); + float f6 = (0.3F * 0.45F) * ((float) i * 0.2F + 1F); + float f7 = (0.3F * 0.45F) * ((float) i * 0.2F + 6F); + + world.spawnParticles(ParticleTypes.SMOKE, player.getX() + f2, player.getY() + (double) f6, player.getZ() + f3, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMOKE, player.getX() - f2, player.getY() + (double) f6, player.getZ() - f3, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMOKE, player.getX() + f4, player.getY() + (double) f7, player.getZ() + f5, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMOKE, player.getX() - f4, player.getY() + (double) f7, player.getZ() - f5, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMALL_FLAME, player.getX() + f2, player.getY() + (double) f6, player.getZ() + f3, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMALL_FLAME, player.getX() - f2, player.getY() + (double) f6, player.getZ() - f3, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMALL_FLAME, player.getX() + f4, player.getY() + (double) f7, player.getZ() + f5, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + world.spawnParticles(ParticleTypes.SMALL_FLAME, player.getX() - f4, player.getY() + (double) f7, player.getZ() - f5, 1, random.nextGaussian() * 0.05D, -0.25, random.nextGaussian() * 0.05D, 0.0D); + } + + @Override + public boolean isAlwaysVisible() { + return false; + } + + @Environment(EnvType.CLIENT) + @Override + protected ClientSuit createClient() { + return new ClientSuit(this) { + @Override + public Supplier model() { + return () -> new SteveSuitModel(this); + } + + @Override + public Identifier texture() { + return new Identifier(this.id().getNamespace(), "textures/suit/fantastic_four.png"); + } + + @Override + public List getVisibleParts(LivingEntity entity) { + // Head and arms. + return VisibilityList.of(VisiblePart.LEFT_SLEEVE, VisiblePart.LEFT_ARM, VisiblePart.RIGHT_SLEEVE, VisiblePart.RIGHT_ARM, VisiblePart.HEAD, VisiblePart.HAT); + } + }; + } +} \ No newline at end of file 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 dfea107e..e6df74a7 100644 --- a/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java +++ b/src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java @@ -1,11 +1,17 @@ package mc.duzo.timeless.suit.set; +import mc.duzo.timeless.power.PowerList; +import mc.duzo.timeless.power.PowerRegistry; +import mc.duzo.timeless.suit.api.SimpleSuitItem; +import mc.duzo.timeless.suit.api.SimpleSuitMaterial; +import mc.duzo.timeless.suit.fantastic.FantasticFourSuit; 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 net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; +import net.minecraft.item.Items; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.SimpleRegistry; @@ -35,6 +41,7 @@ public static T register(T suit) { public static SuitSet MOON_KNIGHT_MARC; public static SuitSet MOON_KNIGHT_JAKE; public static SuitSet MOON_KNIGHT_STEVEN; + public static SuitSet FANTASTIC_INVISIBLE; public static void init() { // Iron Man @@ -45,8 +52,14 @@ public static void init() { // Batman BATMAN_66 = register(new RegisteringSuitSet(new Batman66Suit(), BatmanSuitItem::new)); + + // Moon Knight MOON_KNIGHT_MARC = register(new RegisteringSuitSet(new MarcSuit(), MoonKnightSuitItem::new)); MOON_KNIGHT_JAKE = register(new RegisteringSuitSet(new JakeSuit(), MoonKnightSuitItem::new)); MOON_KNIGHT_STEVEN = register(new RegisteringSuitSet(new StevenSuit(), MoonKnightSuitItem::new)); + + // Fantastic Four + FANTASTIC_INVISIBLE = register(new RegisteringSuitSet(FantasticFourSuit.create(Timeless.id("fantastic_invisible"), PowerList.of(PowerRegistry.INVISIBILITY), () -> SetRegistry.FANTASTIC_INVISIBLE), + (suit, type) -> new SimpleSuitItem(suit, type, new SimpleSuitMaterial(Items.COPPER_INGOT, "fantastic")))); } } diff --git a/src/main/resources/assets/timeless/textures/suit/fantastic_four.png b/src/main/resources/assets/timeless/textures/suit/fantastic_four.png new file mode 100644 index 0000000000000000000000000000000000000000..8efae86a57589b572e61687be340f3c8bb7df81a GIT binary patch literal 1017 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1^2Ka=yhStmoi0cjv@O5#py>;}!x%F#bKECzi>&Jxnxb)eRy{#Jp1AML= zJoMr1TcC~*);EekioYbtFZe$SV7PK;#zLSJXMsm#F#`kNVGw3Kp1&dmC@4|l8c`CQ zpH@AC&ooa@Ed~xChm}E!k(GfF$npYW zX($`yLk&h|us9QtZOF*PAONJJfH_0NEhG1T=>UtTM>b0?2~uGBhv%$*yit6b_zep#fAE;_2cT65;-K z+QUh=6?j?>KA$lm=I_7$+f&N~Rc@5OEd8~7^4udHJwI|1bv%B@zv8W6_Q^l+pV>q6 zd1|EH9`>l~UyBZ^s)vVt-{)xLe7vDM`|PA$-#>{y_{H?#tNM@0A|lF5TME_KJ@RfR zbl4i0>|=CkxcE4uwU<+4>Osw`i#{?$q~|tt%usRYp3Pt$uDo&@C1%D6S=A24tWy3erTX{gi! zjsuR1-)^_8>gArM@K0V(A~!_({+qQTzc~YbsR-RUne#q+=k|Tojk~q#g5oRp{n}X5 zzB_1(sC}pA1M37X?qG`<%t!sZZvI($kAX2M@lk8!;Zn2k`N~W8K5DYxYsJvIHI+fw zq~_c`X5RUq6&FO=F39bh`MiNS@ovqt_>U~xCdh1X{Sv@`#qNYxW9*Acw&hv!!g~$A z`ER|y>MC@0 ziCkf>Yj&KtdtB+)n)M9fJJ~ustFPJDHqB>@Qe9f~Z5D5X$<%Ttfm^fMKPqfkxy}6d z&jXLyITPmReQjfKxmADT9BV*jd;aT-UX8z*50u~MJK*+*D?xy9f@;&-ISjR1UL=at zFs!ljVc>hAX)(coT}#J>;isDQBil1pjSIIOJ=)8f5O~19;Y029xp9kSGW;56>+tiI z Date: Tue, 29 Jul 2025 13:51:56 +0100 Subject: [PATCH 2/2] fix: z fighting on steve/alex suits --- .../timeless/suit/client/render/generic/AlexSuitModel.java | 4 ++++ .../timeless/suit/client/render/generic/SteveSuitModel.java | 4 ++++ .../mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) 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 109b3ffc..9f8698f2 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 @@ -80,6 +80,10 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V } } + float factor = 1.01f; + matrices.scale(factor, factor, factor); + matrices.translate(0.0F, 1 - factor, 1 - factor); + this.getPart().render(matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV, r, g, b, alpha); matrices.pop(); } 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 f8a8513c..173328a8 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 @@ -80,6 +80,10 @@ public void render(LivingEntity entity, float tickDelta, MatrixStack matrices, V } } + float factor = 1.01f; + matrices.scale(factor, factor, factor); + matrices.translate(0.0F, 1 - factor, 1 - factor); + this.getPart().render(matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV, r, g, b, alpha); matrices.pop(); } diff --git a/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java b/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java index a080c903..28ee52a1 100644 --- a/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java +++ b/src/main/java/mc/duzo/timeless/suit/fantastic/FantasticFourSuit.java @@ -137,7 +137,7 @@ public Identifier texture() { @Override public List getVisibleParts(LivingEntity entity) { // Head and arms. - return VisibilityList.of(VisiblePart.LEFT_SLEEVE, VisiblePart.LEFT_ARM, VisiblePart.RIGHT_SLEEVE, VisiblePart.RIGHT_ARM, VisiblePart.HEAD, VisiblePart.HAT); + return VisibilityList.of(VisiblePart.LEFT_ARM, VisiblePart.RIGHT_ARM, VisiblePart.HEAD, VisiblePart.HAT); } }; }