From 5985cd5854fc50bee156e09a84b29ade75f7e691 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 17 Jun 2024 18:02:10 +0800 Subject: [PATCH 01/71] Initial implementation of copycat slope todo: - item model - fix brass casing texture glitching out - block shape --- .../com/copycatsplus/copycats/CCBlocks.java | 12 + .../copycatsplus/copycats/CCCreativeTabs.java | 3 +- .../base/model/assembly/Assembler.java | 22 +- .../base/model/assembly/MutableVec3.java | 18 ++ .../base/model/assembly/QuadRotate.java | 25 ++ .../base/model/assembly/QuadScale.java | 25 ++ .../base/model/assembly/QuadShear.java | 28 ++ .../base/model/assembly/QuadSlope.java | 82 ++++++ .../base/model/assembly/QuadTranslate.java | 26 ++ ...tation.java => TrackingQuadTransform.java} | 22 +- .../copycat/base/model/assembly/UVHelper.java | 17 ++ .../copycat/slope/CopycatSlopeBlock.java | 241 ++++++++++++++++++ .../slope/CopycatSlopeEnhancedModel.java | 102 ++++++++ .../copycat/slope/CopycatSlopeModel.java | 29 +++ .../datagen/recipes/CCStandardRecipes.java | 23 +- .../models/block/copycat_base/slope.json | 23 ++ .../copycats/blockstates/copycat_slope.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../copycats/models/item/copycat_slope.json | 3 + .../misc/stonecutting/copycat_slope.json | 33 +++ .../loot_tables/blocks/copycat_slope.json | 21 ++ .../recipes/stonecutting/copycat_slope.json | 8 + .../copycats/tags/items/copycat_stairs.json | 3 +- .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../model/assembly/fabric/AssemblerImpl.java | 17 +- ...dRotationImpl.java => QuadRotateImpl.java} | 19 +- .../model/assembly/fabric/QuadScaleImpl.java | 28 ++ .../model/assembly/fabric/QuadShearImpl.java | 29 +++ .../assembly/fabric/QuadTranslateImpl.java | 28 ++ .../model/assembly/fabric/UVHelperImpl.java | 78 ++++++ .../copycats/blockstates/copycat_slope.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../copycats/models/item/copycat_slope.json | 3 + .../misc/stonecutting/copycat_slope.json | 33 +++ .../loot_tables/blocks/copycat_slope.json | 21 ++ .../recipes/stonecutting/copycat_slope.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- ...dRotationImpl.java => QuadRotateImpl.java} | 10 +- .../model/assembly/forge/QuadScaleImpl.java | 26 ++ .../model/assembly/forge/QuadShearImpl.java | 27 ++ .../assembly/forge/QuadTranslateImpl.java | 26 ++ .../model/assembly/forge/UVHelperImpl.java | 80 ++++++ 46 files changed, 1150 insertions(+), 79 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java rename common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/{QuadRotation.java => TrackingQuadTransform.java} (68%) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java create mode 100644 common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json create mode 100644 fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope.json create mode 100644 fabric/src/generated/resources/assets/copycats/models/item/copycat_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json rename fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/{QuadRotationImpl.java => QuadRotateImpl.java} (62%) create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java create mode 100644 forge/src/generated/resources/assets/copycats/blockstates/copycat_slope.json create mode 100644 forge/src/generated/resources/assets/copycats/models/item/copycat_slope.json create mode 100644 forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json create mode 100644 forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json create mode 100644 forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json rename forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/{QuadRotationImpl.java => QuadRotateImpl.java} (78%) create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index 3fd87f7b9..cc2a8a338 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -39,6 +39,9 @@ import com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock; import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceBlock; import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceModel; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeBlock; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeEnhancedModel; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsBlock; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsEnhancedModel; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsModel; @@ -474,6 +477,15 @@ public class CCBlocks { .blockstate((c, p) -> getWrappedBlockState(c, p, "wrapped_copycat_wall")) .register(); + public static final BlockEntry COPYCAT_SLOPE = + REGISTRATE.block("copycat_slope", CopycatSlopeBlock::new) + .transform(BuilderTransformers.copycat()) + .transform(FeatureToggle.register()) + .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(), new CopycatSlopeEnhancedModel()))) + .item() + .transform(customItemModel("copycat_base", "slope")) + .register(); + public static @Nullable BlockEntry COPYCAT_TEST_BLOCK; @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index 54d06d1d6..9e8fb1f21 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -38,7 +38,8 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_VERTICAL_STEP, CCBlocks.COPYCAT_WALL, CCBlocks.COPYCAT_WOODEN_BUTTON, - CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE + CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, + CCBlocks.COPYCAT_SLOPE ); @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index cbd344cd5..fab8aa798 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -1,11 +1,11 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.core.Direction; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nullable; import java.util.Objects; public class Assembler { @@ -116,8 +116,24 @@ public static MutableAABB aabb(double sizeX, double sizeY, double sizeZ) { return new MutableAABB(sizeX, sizeY, sizeZ); } - public static QuadRotation rot(MutableVec3.AsPivot pivot, MutableVec3 rot) { - return new QuadRotation(pivot, rot); + public static QuadRotate rotate(MutableVec3.AsPivot pivot, MutableVec3 rot) { + return new QuadRotate(pivot, rot); + } + + public static QuadScale scale(MutableVec3.AsPivot pivot, MutableVec3 scale) { + return new QuadScale(pivot, scale); + } + + public static QuadTranslate translate(double x, double y, double z) { + return new QuadTranslate(x, y, z); + } + + public static QuadSlope slope(Direction face, QuadSlope.QuadSlopeFunction func) { + return new QuadSlope(face, func); + } + + public static QuadShear shear(Direction.Axis axis, Direction direction, double amount) { + return new QuadShear(axis, direction, amount); } public static class CopycatRenderContext { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java index b4ef16d7e..596f51937 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; +import net.minecraft.core.Direction; import net.minecraft.world.phys.Vec3; public class MutableVec3 implements GlobalTransform.Transformable { @@ -77,6 +78,23 @@ public MutableVec3 set(double x, double y, double z) { return this; } + public double get(Direction.Axis axis) { + return switch (axis) { + case X -> x; + case Y -> y; + case Z -> z; + }; + } + + public MutableVec3 set(Direction.Axis axis, double value) { + switch (axis) { + case X -> x = value; + case Y -> y = value; + case Z -> z = value; + } + return this; + } + /** * Marker subclass for when a Vec3 is used as a pivot point */ diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java new file mode 100644 index 000000000..a638b9d4a --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java @@ -0,0 +1,25 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadRotate extends TrackingQuadTransform { + public final Vec3 pivot; + public final Vec3 rotation; + + public QuadRotate(MutableVec3.AsPivot pivot, MutableVec3 rotation) { + this.pivot = pivot.toVec3Unscaled(); + this.rotation = rotation.toVec3Unscaled(); + } + + @Override + public T transformVertices(T vertexData, TextureAtlasSprite sprite) { + return transformVertices(this, vertexData, sprite); + } + + @ExpectPlatform + public static T transformVertices(QuadRotate self, T vertexData, TextureAtlasSprite sprite) { + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java new file mode 100644 index 000000000..9f32890b0 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java @@ -0,0 +1,25 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadScale extends TrackingQuadTransform { + public final Vec3 pivot; + public final Vec3 scale; + + public QuadScale(MutableVec3.AsPivot pivot, MutableVec3 scale) { + this.pivot = pivot.toVec3Unscaled(); + this.scale = scale.toVec3Unscaled(); + } + + @Override + public T transformVertices(T vertexData, TextureAtlasSprite sprite) { + return transformVertices(this, vertexData, sprite); + } + + @ExpectPlatform + public static T transformVertices(QuadScale self, T vertexData, TextureAtlasSprite sprite) { + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java new file mode 100644 index 000000000..a216d6fc2 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java @@ -0,0 +1,28 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; + +public class QuadShear extends TrackingQuadTransform { + public final Axis axis; + public final Direction direction; + public final double amount; + + public QuadShear(Axis axis, Direction direction, double amount) { + this.axis = axis; + this.direction = direction; + this.amount = amount; + } + + @Override + public T transformVertices(T vertexData, TextureAtlasSprite sprite) { + return transformVertices(this, vertexData, sprite); + } + + @ExpectPlatform + public static T transformVertices(QuadShear self, T vertexData, TextureAtlasSprite sprite) { + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java new file mode 100644 index 000000000..5d992f2bc --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java @@ -0,0 +1,82 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; + +public class QuadSlope extends TrackingQuadTransform { + + public final Direction face; + public final QuadSlopeFunction func; + + public QuadSlope(Direction face, QuadSlopeFunction func) { + this.face = face; + this.func = func; + } + + @Override + public T transformVertices(T vertexData, TextureAtlasSprite sprite) { + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + return (T) UVHelper.mapWithUV(vertexData, sprite, (vertex, i) -> { + this.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + double a; + double b; + + switch (this.face.getAxis()) { + case X: + a = mutableVertex.y; + b = mutableVertex.z; + break; + case Y: + a = mutableVertex.x; + b = mutableVertex.z; + break; + case Z: + a = mutableVertex.x; + b = mutableVertex.y; + break; + default: + throw new RuntimeException("Unexpected value: " + this.face.getAxis()); + } + + double output = this.func.apply(a, b); + + switch (this.face.getAxis()) { + case X: + if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { + mutableVertex.x *= output / 16; + } else { + mutableVertex.x = 16 - output * (16 - mutableVertex.x) / 16; + } + break; + case Y: + if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { + mutableVertex.y *= output / 16; + } else { + mutableVertex.y = 16 - output * (16 - mutableVertex.y) / 16; + } + break; + case Z: + if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { + mutableVertex.z *= output / 16; + } else { + mutableVertex.z = 16 - output * (16 - mutableVertex.z) / 16; + } + break; + default: + throw new RuntimeException("Unexpected value: " + this.face.getAxis()); + } + + return this.mutate(mutableVertex).toVec3(); + }); + } + + public static double map(double fromStart, double fromEnd, double toStart, double toEnd, double value) { + return toStart + (value - fromStart) / (fromEnd - fromStart) * (toEnd - toStart); + } + + @FunctionalInterface + public interface QuadSlopeFunction { + double apply(double a, double b); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java new file mode 100644 index 000000000..91921714f --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java @@ -0,0 +1,26 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + +public class QuadTranslate extends TrackingQuadTransform { + public final double x; + public final double y; + public final double z; + + public QuadTranslate(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public T transformVertices(T vertexData, TextureAtlasSprite sprite) { + return transformVertices(this, vertexData, sprite); + } + + @ExpectPlatform + public static T transformVertices(QuadTranslate self, T vertexData, TextureAtlasSprite sprite) { + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotation.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java similarity index 68% rename from common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotation.java rename to common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java index f7932f464..824288b19 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotation.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java @@ -1,33 +1,13 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; import com.copycatsplus.copycats.content.copycat.base.model.assembly.Mutation.MutationType; -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; import java.util.ArrayList; import java.util.List; -public class QuadRotation implements QuadTransform { - public final Vec3 pivot; - public final Vec3 rotation; +public abstract class TrackingQuadTransform implements QuadTransform { List mutations = new ArrayList<>(2); - public QuadRotation(MutableVec3.AsPivot pivot, MutableVec3 rotation) { - this.pivot = pivot.toVec3Unscaled(); - this.rotation = rotation.toVec3Unscaled(); - } - - @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - return transformVertices(this, vertexData, sprite); - } - - @ExpectPlatform - public static T transformVertices(QuadRotation self, T vertexData, TextureAtlasSprite sprite) { - return null; - } - public MutableVec3 mutate(MutableVec3 vec3) { for (Mutation mutation : mutations) { mutation.mutate(vec3); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java new file mode 100644 index 000000000..59c055c66 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java @@ -0,0 +1,17 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class UVHelper { + @ExpectPlatform + public static T mapWithUV(T vertexData, TextureAtlasSprite sprite, QuadVertexMapper mapper) { + return null; + } + + @FunctionalInterface + public interface QuadVertexMapper { + Vec3 map(Vec3 vertex, int vertexIndex); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java new file mode 100644 index 000000000..236a34494 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -0,0 +1,241 @@ +package com.copycatsplus.copycats.content.copycat.slope; + +import com.copycatsplus.copycats.CCBlocks; +import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.IStateType; +import com.simibubi.create.content.equipment.extendoGrip.ExtendoGripItem; +import com.simibubi.create.foundation.placement.IPlacementHelper; +import com.simibubi.create.foundation.placement.PlacementHelpers; +import com.simibubi.create.foundation.placement.PlacementOffset; +import com.simibubi.create.foundation.placement.PoleHelper; +import com.simibubi.create.infrastructure.config.AllConfigs; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.function.Predicate; + +public class CopycatSlopeBlock extends CTWaterloggedCopycatBlock implements IStateType { + + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty HALF = BlockStateProperties.HALF; + + private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); + + public CopycatSlopeBlock(Properties pProperties) { + super(pProperties); + registerDefaultState(defaultBlockState() + .setValue(FACING, Direction.NORTH) + .setValue(HALF, Half.BOTTOM) + ); + } + + @Override + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult ray) { + + if (!player.isShiftKeyDown() && player.mayBuild()) { + ItemStack heldItem = player.getItemInHand(hand); + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem)) { + placementHelper.getOffset(player, world, state, pos, ray) + .placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); + return InteractionResult.SUCCESS; + } + } + + return super.use(state, world, pos, player, hand, ray); + } + + @Override + public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, + BlockPos fromPos, BlockPos toPos) { + Direction direction = state.getValue(FACING); + Half half = state.getValue(HALF); + BlockState toState = reader.getBlockState(toPos); + + if (toState.is(this)) { + // connecting to another copycat beam + return toState.getValue(FACING) != direction || toState.getValue(HALF) != half; + } else { + // doesn't connect to any other blocks + return true; + } + } + + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, + BlockState state) { + BlockState toState = reader.getBlockState(toPos); + if (!toState.is(this)) return false; + Direction facing = state.getValue(FACING); + Half half = state.getValue(HALF); + + BlockPos diff = toPos.subtract(fromPos); + if (diff.equals(Vec3i.ZERO)) { + return true; + } + Direction face = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (face == null) { + return false; + } + + if (toState.is(this)) { + try { + return toState.getValue(FACING) == facing && toState.getValue(HALF) == half && + face.getAxis().isHorizontal() && face.getAxis() != facing.getAxis(); + } catch (IllegalStateException ignored) { + return false; + } + } else { + return false; + } + } + + @SuppressWarnings("deprecation") + @Override + public boolean isPathfindable(@NotNull BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull PathComputationType pType) { + return false; + } + + @Override + public boolean canFaceBeOccluded(BlockState state, Direction face) { + Direction facing = state.getValue(FACING); + Half half = state.getValue(HALF); + if (face == facing) return true; + if (face == facing.getOpposite()) return false; + if (half == Half.TOP) return face != Direction.DOWN; + else return face != Direction.UP; + } + + @Override + public boolean shouldFaceAlwaysRender(BlockState state, Direction face) { + return !canFaceBeOccluded(state, face); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + BlockState stateForPlacement = super.getStateForPlacement(context); + assert stateForPlacement != null; + Direction facing = context.getHorizontalDirection(); + Half half = context.getClickedFace() == Direction.DOWN + ? Half.TOP + : context.getClickedFace() == Direction.UP + ? Half.BOTTOM + : context.getClickLocation().y - context.getClickedPos().getY() > 0.5 + ? Half.TOP + : Half.BOTTOM; + return stateForPlacement.setValue(FACING, facing).setValue(HALF, half); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + super.createBlockStateDefinition(pBuilder.add(FACING, HALF)); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull VoxelShape getShape(BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull CollisionContext pContext) { + return Shapes.block(); // todo: slope shape + } + + + public boolean supportsExternalFaceHiding(BlockState state) { + return true; + } + + + public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, + Direction dir) { + if (state.is(this) == neighborState.is(this)) { + if (getMaterial(level, pos).skipRendering(getMaterial(level, pos.relative(dir)), dir.getOpposite())) { + Direction facing = state.getValue(FACING); + Half half = state.getValue(HALF); + return neighborState.getValue(FACING) == facing && + neighborState.getValue(HALF) == half && + dir.getAxis().isHorizontal() && dir.getAxis() != facing.getAxis(); + } + } + + return false; + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState rotate(@NotNull BlockState pState, Rotation pRot) { + return pState.setValue(FACING, pRot.rotate(pState.getValue(FACING))); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState mirror(@NotNull BlockState pState, @NotNull Mirror pMirror) { + return pState.setValue(FACING, pMirror.mirror(pState.getValue(FACING))); + } + + @MethodsReturnNonnullByDefault + private static class PlacementHelper extends PoleHelper { + + private PlacementHelper() { + super(CCBlocks.COPYCAT_HALF_PANEL::has, state -> state.getValue(FACING).getClockWise().getAxis(), FACING); + } + + @Override + public Predicate getItemPredicate() { + return i -> i.getItem() instanceof BlockItem + && (((BlockItem) i.getItem()).getBlock() instanceof CopycatSlopeBlock); + } + + @Override + public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos, BlockHitResult ray) { + List directions = IPlacementHelper.orderedByDistance(pos, ray.getLocation(), dir -> dir.getAxis() == axisFunction.apply(state)); + for (Direction dir : directions) { + int range = AllConfigs.server().equipment.placementAssistRange.get(); + if (player != null) { + //TODO: Add way to get reach attribute from platform + AttributeInstance reach = null; + if (reach != null && reach.hasModifier(ExtendoGripItem.singleRangeAttributeModifier)) + range += 4; + } + int poles = attachedPoles(world, pos, dir); + if (poles >= range) + continue; + + BlockPos newPos = pos.relative(dir, poles + 1); + BlockState newState = world.getBlockState(newPos); + + if (newState.canBeReplaced()) + return PlacementOffset.success(newPos, bState -> bState.setValue(property, state.getValue(property)).setValue(HALF, state.getValue(HALF))); + + } + + return PlacementOffset.fail(); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java new file mode 100644 index 000000000..a7ce63497 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java @@ -0,0 +1,102 @@ +package com.copycatsplus.copycats.content.copycat.slope; + +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Half; + +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadSlope.map; + +public class CopycatSlopeEnhancedModel implements SimpleCopycatPart { + + private static final double MARGIN = 2; + private static final double MARGIN_ADJ = MARGIN / Math.tan(Math.toRadians(22.5)); + private static final double MID_LENGTH = 16 * Math.sqrt(2) - 2 * MARGIN_ADJ; + private static final double ALIGNED_LENGTH = ((int) Math.floor(MID_LENGTH)) % 2 == 0 ? Math.floor(MID_LENGTH) : Math.floor(MID_LENGTH) + 1; + + @Override + public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { + Direction facing = state.getValue(CopycatSlopeBlock.FACING); + Half half = state.getValue(CopycatSlopeBlock.HALF); + int rot = (int) facing.toYRot(); + boolean flipY = half == Half.TOP; + GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, MARGIN_ADJ), + cull(UP | NORTH | SOUTH), + slope(Direction.UP, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b)) + ); + assemblePiece(context, + transform, + vec3(0, 0, MARGIN_ADJ), + aabb(16, 16, 16 - MARGIN - MARGIN_ADJ).move(0, 0, MARGIN_ADJ), + cull(UP | NORTH | SOUTH), + slope(Direction.UP, (a, b) -> map(MARGIN_ADJ, 16 - MARGIN, MARGIN, 16 - MARGIN_ADJ, b)) + ); + assemblePiece(context, + transform, + vec3(0, 0, 16 - MARGIN), + aabb(16, 16, MARGIN).move(0, 0, 16 - MARGIN), + cull(UP | NORTH), + slope(Direction.UP, (a, b) -> map(16 - MARGIN, 16, 16 - MARGIN_ADJ, 16, b)) + ); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, MARGIN_ADJ), + cull(DOWN | NORTH | SOUTH), + slope(Direction.DOWN, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b)), + translate(0, -16, 0), + rotate( + pivot(0, 0, 0), + vec3(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 16 - MARGIN, 16 - ALIGNED_LENGTH / 2), + aabb(16, MARGIN, ALIGNED_LENGTH / 2).move(0, 16 - MARGIN, Math.floor((16 - ALIGNED_LENGTH / 2) / 2)), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, 16, 16), + vec3(1, 1, MID_LENGTH / ALIGNED_LENGTH) + ), + translate(0, 0, -MARGIN_ADJ - MID_LENGTH / 2), + rotate( + pivot(16, 16, 16), + vec3(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 16 - MARGIN, 16 - ALIGNED_LENGTH / 2), + aabb(16, MARGIN, ALIGNED_LENGTH / 2).move(0, 16 - MARGIN, Math.floor((16 - ALIGNED_LENGTH / 2) / 2)), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, 16, 16), + vec3(1, 1, MID_LENGTH / ALIGNED_LENGTH) + ), + translate(0, 0, -MARGIN_ADJ), + rotate( + pivot(16, 16, 16), + vec3(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 0, 16 - MARGIN_ADJ), + aabb(16, 16, MARGIN_ADJ).move(0, 0, 16 - MARGIN_ADJ), + cull(DOWN | NORTH | SOUTH), + slope(Direction.DOWN, (a, b) -> map(16 - MARGIN_ADJ, 16, MARGIN, 0, b)), + rotate( + pivot(16, 16, 16), + vec3(-45, 0, 0) + ) + ); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java new file mode 100644 index 000000000..035d7f085 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -0,0 +1,29 @@ +package com.copycatsplus.copycats.content.copycat.slope; + +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Half; + +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.NORTH; + +public class CopycatSlopeModel implements SimpleCopycatPart { + + @Override + public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { + Direction facing = state.getValue(CopycatSlopeBlock.FACING); + Half half = state.getValue(CopycatSlopeBlock.HALF); + int rot = (int) facing.toYRot(); + boolean flipY = half == Half.TOP; + GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, 16), + cull(NORTH), + slope(Direction.UP, (a, b) -> b) + ); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java index 2fd7dcab2..c425a71e0 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java @@ -3,7 +3,6 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCItems; import com.copycatsplus.copycats.CCTags; -import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; import com.copycatsplus.copycats.datagen.recipes.gen.CopycatsRecipeProvider; import com.copycatsplus.copycats.datagen.recipes.gen.GeneratedRecipeBuilder; @@ -12,33 +11,24 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.foundation.utility.RegisteredObjects; -import com.tterrag.registrate.util.entry.BlockEntry; import com.tterrag.registrate.util.entry.ItemProviderEntry; import com.tterrag.registrate.util.entry.RegistryEntry; import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.advancements.critereon.ItemPredicate; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.PackOutput; -import net.minecraft.data.recipes.*; -import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.SimpleCookingSerializer; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.Block; -import java.util.*; -import java.util.function.Consumer; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.function.Supplier; -import java.util.function.UnaryOperator; import java.util.stream.Collectors; -import static com.copycatsplus.copycats.datagen.recipes.gen.GeneratedRecipeBuilder.*; +import static com.copycatsplus.copycats.datagen.recipes.gen.GeneratedRecipeBuilder.GeneratedRecipe; public class CCStandardRecipes extends CopycatsRecipeProvider { @@ -179,8 +169,11 @@ public class CCStandardRecipes extends CopycatsRecipeProvider { GeneratedRecipe COPYCAT_LADDER = copycat(CCBlocks.COPYCAT_LADDER, 6); + GeneratedRecipe COPYCAT_SLOPE = copycat(CCBlocks.COPYCAT_SLOPE, 2); + String currentFolder = ""; + Marker enterFolder(String folder) { currentFolder = folder; return new Marker(); diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json new file mode 100644 index 000000000..6b928d8f3 --- /dev/null +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json @@ -0,0 +1,23 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/copycat_base", + "2": "create:block/copycat_base", + "particle": "create:block/copycat_base" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope.json b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json index c8bec0117..b15de372a 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json @@ -95,6 +95,7 @@ "block.copycats.copycat_slice.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", "block.copycats.copycat_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_slope": "ǝdoןS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs": "sɹıɐʇS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_us.json b/fabric/src/generated/resources/assets/copycats/lang/en_us.json index 6db8358b3..297e3a7a3 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_us.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_us.json @@ -95,6 +95,7 @@ "block.copycats.copycat_slice.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", "block.copycats.copycat_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_slice.tooltip.summary": "_Converts_ any _full block_ into decorative slices. Slices can be enlarged till it reaches a full block in size.", + "block.copycats.copycat_slope": "Copycat Slope", "block.copycats.copycat_stairs": "Copycat Stairs", "block.copycats.copycat_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope.json b/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope.json new file mode 100644 index 000000000..0c6296a0b --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json new file mode 100644 index 000000000..9f9d4a076 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "c:zinc_ingots" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_slope" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_slope" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json new file mode 100644 index 000000000..ebad16c4f --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_slope" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json new file mode 100644 index 000000000..9486ff86a --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "c:zinc_ingots" + }, + "result": "copycats:copycat_slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/tags/items/copycat_stairs.json b/fabric/src/generated/resources/data/copycats/tags/items/copycat_stairs.json index 283c93b30..228a9d95c 100644 --- a/fabric/src/generated/resources/data/copycats/tags/items/copycat_stairs.json +++ b/fabric/src/generated/resources/data/copycats/tags/items/copycat_stairs.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ - "copycats:copycat_stairs" + "copycats:copycat_stairs", + "copycats:copycat_vertical_stairs" ] } \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index de4e3df8b..69cd8d562 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -25,6 +25,7 @@ "copycats:copycat_trapdoor", "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", - "copycats:copycat_wall" + "copycats:copycat_wall", + "copycats:copycat_slope" ] } \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index de4e3df8b..69cd8d562 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -25,6 +25,7 @@ "copycats:copycat_trapdoor", "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", - "copycats:copycat_wall" + "copycats:copycat_wall", + "copycats:copycat_slope" ] } \ No newline at end of file diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java index 87043228b..ec5a15c0e 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java @@ -2,7 +2,6 @@ import com.copycatsplus.copycats.content.copycat.base.model.assembly.*; import com.simibubi.create.foundation.model.BakedModelHelper; -import com.simibubi.create.foundation.model.BakedQuadHelper; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.model.SpriteFinder; @@ -12,10 +11,7 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -import java.util.ArrayList; -import java.util.List; - -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; public class AssemblerImpl { @@ -77,18 +73,9 @@ public static dest.copyFrom(src); TextureAtlasSprite sprite = spriteFinder.find(src); BakedModelHelper.cropAndMove(dest, sprite, crop, move); - List vertices = new ArrayList<>(4); - vertices.add(BakedQuadHelper.getXYZ(dest, 0)); - vertices.add(BakedQuadHelper.getXYZ(dest, 1)); - vertices.add(BakedQuadHelper.getXYZ(dest, 2)); - vertices.add(BakedQuadHelper.getXYZ(dest, 3)); for (QuadTransform transform : transforms) { - vertices = transform.transformVertices(vertices, sprite); + src = transform.transformVertices(src, sprite); } - BakedQuadHelper.setXYZ(dest, 0, vertices.get(0)); - BakedQuadHelper.setXYZ(dest, 1, vertices.get(1)); - BakedQuadHelper.setXYZ(dest, 2, vertices.get(2)); - BakedQuadHelper.setXYZ(dest, 3, vertices.get(3)); } public static class CopycatRenderContextFabric extends CopycatRenderContext { diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotationImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java similarity index 62% rename from fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotationImpl.java rename to fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java index 5a8bbe48f..d0a4d2f5a 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotationImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java @@ -1,29 +1,24 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotation; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotate; import com.simibubi.create.foundation.model.BakedQuadHelper; import com.simibubi.create.foundation.utility.VecHelper; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.world.phys.Vec3; -import java.util.List; - -public class QuadRotationImpl extends QuadRotation { - - public QuadRotationImpl(MutableVec3.AsPivot pivot, MutableVec3 rotation) { - super(pivot, rotation); - } +public class QuadRotateImpl { @SuppressWarnings("unchecked") - public static T transformVertices(QuadRotation self, T data, TextureAtlasSprite sprite) { - List vertexData = (List) data; + public static T transformVertices(QuadRotate self, T data, TextureAtlasSprite sprite) { + MutableQuadView vertexData = (MutableQuadView) data; MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { - Vec3 vertex = vertexData.get(i); + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3Unscaled().subtract(self.pivot), self.rotation).add(self.pivot); - vertexData.set(i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); } return (T) vertexData; } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java new file mode 100644 index 000000000..fac6c9c00 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java @@ -0,0 +1,28 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadScale; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadScaleImpl { + + @SuppressWarnings("unchecked") + public static T transformVertices(QuadScale self, T data, TextureAtlasSprite sprite) { + MutableQuadView vertexData = (MutableQuadView) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; + mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; + mutableVertex.z = (mutableVertex.z - self.pivot.z) * self.scale.z + self.pivot.z; + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java new file mode 100644 index 000000000..e89ee1d30 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java @@ -0,0 +1,29 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadShear; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.Vec3; + +public class QuadShearImpl { + + @SuppressWarnings("unchecked") + public static T transformVertices(QuadShear self, T data, TextureAtlasSprite sprite) { + MutableQuadView vertexData = (MutableQuadView) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + double shearAxis = mutableVertex.get(self.axis); + double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); + mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis / 16 * amount); + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java new file mode 100644 index 000000000..ee81780de --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java @@ -0,0 +1,28 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadTranslate; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadTranslateImpl { + + @SuppressWarnings("unchecked") + public static T transformVertices(QuadTranslate self, T data, TextureAtlasSprite sprite) { + MutableQuadView vertexData = (MutableQuadView) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + mutableVertex.x += self.x; + mutableVertex.y += self.y; + mutableVertex.z += self.z; + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java new file mode 100644 index 000000000..9c0c0f915 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java @@ -0,0 +1,78 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.UVHelper; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU; +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV; + +public class UVHelperImpl { + public static T mapWithUV(T data, TextureAtlasSprite sprite, UVHelper.QuadVertexMapper mapper) { + MutableQuadView quad = (MutableQuadView) data; + Vec3 xyz0 = BakedQuadHelper.getXYZ(quad, 0); + Vec3 xyz1 = BakedQuadHelper.getXYZ(quad, 1); + Vec3 xyz2 = BakedQuadHelper.getXYZ(quad, 2); + Vec3 xyz3 = BakedQuadHelper.getXYZ(quad, 3); + + Vec3 uAxis = xyz3.add(xyz2) + .scale(.5); + Vec3 vAxis = xyz1.add(xyz2) + .scale(.5); + Vec3 center = xyz3.add(xyz2) + .add(xyz0) + .add(xyz1) + .scale(.25); + + float u0 = quad.spriteU(0, 0); + float u3 = quad.spriteU(3, 0); + float v0 = quad.spriteV(0, 0); + float v1 = quad.spriteV(1, 0); + + float uScale = (float) Math + .round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0)); + float vScale = (float) Math + .round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0)); + + if (uScale == 0) { + float v3 = quad.spriteV(3, 0); + float u1 = quad.spriteU(1, 0); + uAxis = xyz1.add(xyz2) + .scale(.5); + vAxis = xyz3.add(xyz2) + .scale(.5); + uScale = (float) Math + .round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0)); + vScale = (float) Math + .round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0)); + + } + + uAxis = uAxis.subtract(center) + .normalize(); + vAxis = vAxis.subtract(center) + .normalize(); + + for (int vertex = 0; vertex < 4; vertex++) { + Vec3 xyz = BakedQuadHelper.getXYZ(quad, vertex); + Vec3 newXyz = mapper.map(xyz, vertex); + Vec3 diff = newXyz.subtract(xyz); + + if (diff.lengthSqr() > 0) { + float u = quad.spriteU(vertex, 0); + float v = quad.spriteV(vertex, 0); + float uDiff = (float) uAxis.dot(diff) * uScale; + float vDiff = (float) vAxis.dot(diff) * vScale; + quad.sprite(vertex, 0, + sprite.getU(getUnInterpolatedU(sprite, u) + uDiff), + sprite.getV(getUnInterpolatedV(sprite, v) + vDiff)); + } + + BakedQuadHelper.setXYZ(quad, vertex, newXyz); + } + + return data; + } +} diff --git a/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope.json b/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/lang/en_ud.json b/forge/src/generated/resources/assets/copycats/lang/en_ud.json index c8bec0117..b15de372a 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_ud.json @@ -95,6 +95,7 @@ "block.copycats.copycat_slice.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", "block.copycats.copycat_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_slope": "ǝdoןS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs": "sɹıɐʇS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/forge/src/generated/resources/assets/copycats/lang/en_us.json b/forge/src/generated/resources/assets/copycats/lang/en_us.json index 6db8358b3..297e3a7a3 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_us.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_us.json @@ -95,6 +95,7 @@ "block.copycats.copycat_slice.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", "block.copycats.copycat_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_slice.tooltip.summary": "_Converts_ any _full block_ into decorative slices. Slices can be enlarged till it reaches a full block in size.", + "block.copycats.copycat_slope": "Copycat Slope", "block.copycats.copycat_stairs": "Copycat Stairs", "block.copycats.copycat_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/forge/src/generated/resources/assets/copycats/models/item/copycat_slope.json b/forge/src/generated/resources/assets/copycats/models/item/copycat_slope.json new file mode 100644 index 000000000..0c6296a0b --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/models/item/copycat_slope.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json new file mode 100644 index 000000000..b88f50311 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "forge:ingots/zinc" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_slope" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_slope" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json new file mode 100644 index 000000000..ebad16c4f --- /dev/null +++ b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_slope" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json new file mode 100644 index 000000000..76e7dc445 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "forge:ingots/zinc" + }, + "result": "copycats:copycat_slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index a0009a246..98ded5df5 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -24,6 +24,7 @@ "copycats:copycat_trapdoor", "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", - "copycats:copycat_wall" + "copycats:copycat_wall", + "copycats:copycat_slope" ] } \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index a0009a246..98ded5df5 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -24,6 +24,7 @@ "copycats:copycat_trapdoor", "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", - "copycats:copycat_wall" + "copycats:copycat_wall", + "copycats:copycat_slope" ] } \ No newline at end of file diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotationImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java similarity index 78% rename from forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotationImpl.java rename to forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java index 3fa51c1c8..08acc709b 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotationImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java @@ -1,19 +1,15 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotation; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotate; import com.simibubi.create.foundation.model.BakedQuadHelper; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.world.phys.Vec3; -public class QuadRotationImpl extends QuadRotation { +public class QuadRotateImpl { - public QuadRotationImpl(MutableVec3.AsPivot pivot, MutableVec3 rotation) { - super(pivot, rotation); - } - - public static T transformVertices(QuadRotation self, T data, TextureAtlasSprite sprite) { + public static T transformVertices(QuadRotate self, T data, TextureAtlasSprite sprite) { int[] vertexData = (int[]) data; MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java new file mode 100644 index 000000000..bf5c1ffcd --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java @@ -0,0 +1,26 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadScale; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadScaleImpl { + + public static T transformVertices(QuadScale self, T data, TextureAtlasSprite sprite) { + int[] vertexData = (int[]) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; + mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; + mutableVertex.z = (mutableVertex.z - self.pivot.z) * self.scale.z + self.pivot.z; + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java new file mode 100644 index 000000000..86f590c28 --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java @@ -0,0 +1,27 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadShear; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.Vec3; + +public class QuadShearImpl { + + public static T transformVertices(QuadShear self, T data, TextureAtlasSprite sprite) { + int[] vertexData = (int[]) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + double shearAxis = mutableVertex.get(self.axis); + double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); + mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis / 16 * amount); + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java new file mode 100644 index 000000000..8cb9a2f41 --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java @@ -0,0 +1,26 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadTranslate; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +public class QuadTranslateImpl { + + public static T transformVertices(QuadTranslate self, T data, TextureAtlasSprite sprite) { + int[] vertexData = (int[]) data; + MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); + for (int i = 0; i < 4; i++) { + Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); + self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + + mutableVertex.x += self.x; + mutableVertex.y += self.y; + mutableVertex.z += self.z; + + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); + } + return (T) vertexData; + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java new file mode 100644 index 000000000..3dcec364f --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java @@ -0,0 +1,80 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.UVHelper; +import com.simibubi.create.foundation.model.BakedQuadHelper; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.world.phys.Vec3; + +import java.util.Arrays; + +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU; +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV; + +public class UVHelperImpl { + public static T mapWithUV(T data, TextureAtlasSprite sprite, UVHelper.QuadVertexMapper mapper) { + int[] vertexData = (int[]) data; + vertexData = Arrays.copyOf(vertexData, vertexData.length); + + Vec3 xyz0 = BakedQuadHelper.getXYZ(vertexData, 0); + Vec3 xyz1 = BakedQuadHelper.getXYZ(vertexData, 1); + Vec3 xyz2 = BakedQuadHelper.getXYZ(vertexData, 2); + Vec3 xyz3 = BakedQuadHelper.getXYZ(vertexData, 3); + + Vec3 uAxis = xyz3.add(xyz2) + .scale(.5); + Vec3 vAxis = xyz1.add(xyz2) + .scale(.5); + Vec3 center = xyz3.add(xyz2) + .add(xyz0) + .add(xyz1) + .scale(.25); + + float u0 = BakedQuadHelper.getU(vertexData, 0); + float u3 = BakedQuadHelper.getU(vertexData, 3); + float v0 = BakedQuadHelper.getV(vertexData, 0); + float v1 = BakedQuadHelper.getV(vertexData, 1); + + float uScale = (float) Math + .round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0)); + float vScale = (float) Math + .round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0)); + + if (uScale == 0) { + float v3 = BakedQuadHelper.getV(vertexData, 3); + float u1 = BakedQuadHelper.getU(vertexData, 1); + uAxis = xyz1.add(xyz2) + .scale(.5); + vAxis = xyz3.add(xyz2) + .scale(.5); + uScale = (float) Math + .round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0)); + vScale = (float) Math + .round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0)); + + } + + uAxis = uAxis.subtract(center) + .normalize(); + vAxis = vAxis.subtract(center) + .normalize(); + + for (int vertex = 0; vertex < 4; vertex++) { + Vec3 xyz = BakedQuadHelper.getXYZ(vertexData, vertex); + Vec3 newXyz = mapper.map(xyz, vertex); + Vec3 diff = newXyz.subtract(xyz); + + if (diff.lengthSqr() > 0) { + float u = BakedQuadHelper.getU(vertexData, vertex); + float v = BakedQuadHelper.getV(vertexData, vertex); + float uDiff = (float) uAxis.dot(diff) * uScale; + float vDiff = (float) vAxis.dot(diff) * vScale; + BakedQuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff)); + BakedQuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff)); + } + + BakedQuadHelper.setXYZ(vertexData, vertex, newXyz); + } + + return (T) vertexData; + } +} From a75fbe5e4b3cb412d063c8c8431b8323cd00957e Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 17 Jun 2024 21:10:42 +0800 Subject: [PATCH 02/71] Reduce the number of conversions between voxel space and block space --- .../base/model/assembly/Assembler.java | 24 ++++++---- .../base/model/assembly/MutableAABB.java | 45 ++++++++++++------ .../base/model/assembly/MutableVec3.java | 46 ++++++++++++------- .../base/model/assembly/QuadRotate.java | 6 +-- .../base/model/assembly/QuadScale.java | 6 +-- .../base/model/assembly/QuadSlope.java | 14 +++--- .../slope/CopycatSlopeEnhancedModel.java | 12 ++--- .../model/assembly/fabric/AssemblerImpl.java | 4 +- .../model/assembly/fabric/QuadRotateImpl.java | 4 +- .../model/assembly/fabric/QuadScaleImpl.java | 2 +- .../model/assembly/fabric/QuadShearImpl.java | 4 +- .../assembly/fabric/QuadTranslateImpl.java | 2 +- .../model/assembly/forge/AssemblerImpl.java | 4 +- .../model/assembly/forge/QuadRotateImpl.java | 4 +- .../model/assembly/forge/QuadScaleImpl.java | 2 +- .../model/assembly/forge/QuadShearImpl.java | 4 +- .../assembly/forge/QuadTranslateImpl.java | 2 +- 17 files changed, 113 insertions(+), 72 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index fab8aa798..c8e6560ae 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -105,35 +105,43 @@ public static MutableCullFace cull(int mask) { } public static MutableVec3 vec3(double x, double y, double z) { - return new MutableVec3(x, y, z); + return new MutableVec3(x / 16, y / 16, z / 16); } public static MutableVec3.AsPivot pivot(double x, double y, double z) { - return new MutableVec3.AsPivot(x, y, z); + return new MutableVec3.AsPivot(x / 16, y / 16, z / 16); + } + + public static MutableVec3.AsAngle angle(double x, double y, double z) { + return new MutableVec3.AsAngle(x, y, z); + } + + public static MutableVec3.AsScale scale(double x, double y, double z) { + return new MutableVec3.AsScale(x, y, z); } public static MutableAABB aabb(double sizeX, double sizeY, double sizeZ) { - return new MutableAABB(sizeX, sizeY, sizeZ); + return new MutableAABB(sizeX / 16, sizeY / 16, sizeZ / 16); } - public static QuadRotate rotate(MutableVec3.AsPivot pivot, MutableVec3 rot) { + public static QuadRotate rotate(MutableVec3.AsPivot pivot, MutableVec3.AsAngle rot) { return new QuadRotate(pivot, rot); } - public static QuadScale scale(MutableVec3.AsPivot pivot, MutableVec3 scale) { + public static QuadScale scale(MutableVec3.AsPivot pivot, MutableVec3.AsScale scale) { return new QuadScale(pivot, scale); } public static QuadTranslate translate(double x, double y, double z) { - return new QuadTranslate(x, y, z); + return new QuadTranslate(x / 16, y / 16, z / 16); } public static QuadSlope slope(Direction face, QuadSlope.QuadSlopeFunction func) { - return new QuadSlope(face, func); + return new QuadSlope(face, (a, b) -> func.apply(a * 16, b * 16) / 16); } public static QuadShear shear(Direction.Axis axis, Direction direction, double amount) { - return new QuadShear(axis, direction, amount); + return new QuadShear(axis, direction, amount / 16); } public static class CopycatRenderContext { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableAABB.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableAABB.java index 9ce9bcbd9..4d24a25a2 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableAABB.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableAABB.java @@ -14,7 +14,26 @@ public MutableAABB(double sizeX, double sizeY, double sizeZ) { set(0, 0, 0, sizeX, sizeY, sizeZ); } + /** + * Move the entire AABB by the given amount in VOXEL SPACE + */ public MutableAABB move(double dX, double dY, double dZ) { + dX /= 16; + dY /= 16; + dZ /= 16; + minX += dX; + maxX += dX; + minY += dY; + maxY += dY; + minZ += dZ; + maxZ += dZ; + return this; + } + + /** + * Move the entire AABB by the given amount in BLOCK SPACE + */ + public MutableAABB shift(double dX, double dY, double dZ) { minX += dX; maxX += dX; minY += dY; @@ -29,9 +48,9 @@ public MutableAABB rotateY(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(16 - minZ, minY, minX, 16 - maxZ, maxY, maxX); - case 180 -> set(16 - minX, minY, 16 - minZ, 16 - maxX, maxY, 16 - maxZ); - case 270 -> set(minZ, minY, 16 - minX, maxZ, maxY, 16 - maxX); + case 90 -> set(1 - minZ, minY, minX, 1 - maxZ, maxY, maxX); + case 180 -> set(1 - minX, minY, 1 - minZ, 1 - maxX, maxY, 1 - maxZ); + case 270 -> set(minZ, minY, 1 - minX, maxZ, maxY, 1 - maxX); default -> this; }; } @@ -41,9 +60,9 @@ public MutableAABB rotateX(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(minX, minZ, 16 - minY, maxX, maxZ, 16 - maxY); - case 180 -> set(minX, 16 - minY, 16 - minZ, maxX, 16 - maxY, 16 - maxZ); - case 270 -> set(minX, 16 - minZ, minY, maxX, 16 - maxZ, maxY); + case 90 -> set(minX, minZ, 1 - minY, maxX, maxZ, 1 - maxY); + case 180 -> set(minX, 1 - minY, 1 - minZ, maxX, 1 - maxY, 1 - maxZ); + case 270 -> set(minX, 1 - minZ, minY, maxX, 1 - maxZ, maxY); default -> this; }; } @@ -53,30 +72,30 @@ public MutableAABB rotateZ(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(minY, 16 - minX, minZ, maxY, 16 - maxX, maxZ); - case 180 -> set(16 - minX, 16 - minY, minZ, 16 - maxX, 16 - maxY, maxZ); - case 270 -> set(16 - minY, minX, minZ, 16 - maxY, maxX, maxZ); + case 90 -> set(minY, 1 - minX, minZ, maxY, 1 - maxX, maxZ); + case 180 -> set(1 - minX, 1 - minY, minZ, 1 - maxX, 1 - maxY, maxZ); + case 270 -> set(1 - minY, minX, minZ, 1 - maxY, maxX, maxZ); default -> this; }; } public MutableAABB flipX(boolean flip) { if (!flip) return this; - return set(16 - minX, minY, minZ, 16 - maxX, maxY, maxZ); + return set(1 - minX, minY, minZ, 1 - maxX, maxY, maxZ); } public MutableAABB flipY(boolean flip) { if (!flip) return this; - return set(minX, 16 - minY, minZ, maxX, 16 - maxY, maxZ); + return set(minX, 1 - minY, minZ, maxX, 1 - maxY, maxZ); } public MutableAABB flipZ(boolean flip) { if (!flip) return this; - return set(minX, minY, 16 - minZ, maxX, maxY, 16 - maxZ); + return set(minX, minY, 1 - minZ, maxX, maxY, 1 - maxZ); } public AABB toAABB() { - return new AABB(minX / 16f, minY / 16f, minZ / 16f, maxX / 16f, maxY / 16f, maxZ / 16f); + return new AABB(minX, minY, minZ, maxX, maxY, maxZ); } public MutableAABB set(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java index 596f51937..e44b4f24f 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java @@ -17,9 +17,9 @@ public MutableVec3 rotateY(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(16 - z, y, x); - case 180 -> set(16 - x, y, 16 - z); - case 270 -> set(z, y, 16 - x); + case 90 -> set(1 - z, y, x); + case 180 -> set(1 - x, y, 1 - z); + case 270 -> set(z, y, 1 - x); default -> this; }; } @@ -29,9 +29,9 @@ public MutableVec3 rotateX(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(x, z, 16 - y); - case 180 -> set(x, 16 - y, 16 - z); - case 270 -> set(x, 16 - z, y); + case 90 -> set(x, z, 1 - y); + case 180 -> set(x, 1 - y, 1 - z); + case 270 -> set(x, 1 - z, y); default -> this; }; } @@ -41,33 +41,29 @@ public MutableVec3 rotateZ(int angle) { angle = angle % 360; if (angle < 0) angle += 360; return switch (angle) { - case 90 -> set(y, 16 - x, z); - case 180 -> set(16 - x, 16 - y, z); - case 270 -> set(16 - y, x, z); + case 90 -> set(y, 1 - x, z); + case 180 -> set(1 - x, 1 - y, z); + case 270 -> set(1 - y, x, z); default -> this; }; } public MutableVec3 flipX(boolean flip) { if (!flip) return this; - return set(16 - x, y, z); + return set(1 - x, y, z); } public MutableVec3 flipY(boolean flip) { if (!flip) return this; - return set(x, 16 - y, z); + return set(x, 1 - y, z); } public MutableVec3 flipZ(boolean flip) { if (!flip) return this; - return set(x, y, 16 - z); + return set(x, y, 1 - z); } public Vec3 toVec3() { - return new Vec3(x / 16f, y / 16f, z / 16f); - } - - public Vec3 toVec3Unscaled() { return new Vec3(x, y, z); } @@ -103,4 +99,22 @@ public AsPivot(double x, double y, double z) { super(x, y, z); } } + + /** + * Marker subclass for when a Vec3 is used as axis-angle rotation + */ + public static class AsAngle extends MutableVec3 { + public AsAngle(double x, double y, double z) { + super(x, y, z); + } + } + + /** + * Marker subclass for when a Vec3 is used as a scale factor + */ + public static class AsScale extends MutableVec3 { + public AsScale(double x, double y, double z) { + super(x, y, z); + } + } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java index a638b9d4a..281bbcc56 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java @@ -8,9 +8,9 @@ public class QuadRotate extends TrackingQuadTransform { public final Vec3 pivot; public final Vec3 rotation; - public QuadRotate(MutableVec3.AsPivot pivot, MutableVec3 rotation) { - this.pivot = pivot.toVec3Unscaled(); - this.rotation = rotation.toVec3Unscaled(); + public QuadRotate(MutableVec3.AsPivot pivot, MutableVec3.AsAngle rotation) { + this.pivot = pivot.toVec3(); + this.rotation = rotation.toVec3(); } @Override diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java index 9f32890b0..96f49dbc5 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java @@ -8,9 +8,9 @@ public class QuadScale extends TrackingQuadTransform { public final Vec3 pivot; public final Vec3 scale; - public QuadScale(MutableVec3.AsPivot pivot, MutableVec3 scale) { - this.pivot = pivot.toVec3Unscaled(); - this.scale = scale.toVec3Unscaled(); + public QuadScale(MutableVec3.AsPivot pivot, MutableVec3.AsScale scale) { + this.pivot = pivot.toVec3(); + this.scale = scale.toVec3(); } @Override diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java index 5d992f2bc..dc1bbdab8 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java @@ -17,7 +17,7 @@ public QuadSlope(Direction face, QuadSlopeFunction func) { public T transformVertices(T vertexData, TextureAtlasSprite sprite) { MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); return (T) UVHelper.mapWithUV(vertexData, sprite, (vertex, i) -> { - this.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + this.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); double a; double b; @@ -44,23 +44,23 @@ public T transformVertices(T vertexData, TextureAtlasSprite sprite) { switch (this.face.getAxis()) { case X: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.x *= output / 16; + mutableVertex.x *= output; } else { - mutableVertex.x = 16 - output * (16 - mutableVertex.x) / 16; + mutableVertex.x = 1 - output * (1 - mutableVertex.x); } break; case Y: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.y *= output / 16; + mutableVertex.y *= output; } else { - mutableVertex.y = 16 - output * (16 - mutableVertex.y) / 16; + mutableVertex.y = 1 - output * (1 - mutableVertex.y); } break; case Z: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.z *= output / 16; + mutableVertex.z *= output; } else { - mutableVertex.z = 16 - output * (16 - mutableVertex.z) / 16; + mutableVertex.z = 1 - output * (1 - mutableVertex.z); } break; default: diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java index a7ce63497..206edb7e1 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java @@ -54,7 +54,7 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex translate(0, -16, 0), rotate( pivot(0, 0, 0), - vec3(-45, 0, 0) + angle(-45, 0, 0) ) ); assemblePiece(context, @@ -64,12 +64,12 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex cull(DOWN | NORTH | SOUTH), scale( pivot(16, 16, 16), - vec3(1, 1, MID_LENGTH / ALIGNED_LENGTH) + scale(1, 1, MID_LENGTH / ALIGNED_LENGTH) ), translate(0, 0, -MARGIN_ADJ - MID_LENGTH / 2), rotate( pivot(16, 16, 16), - vec3(-45, 0, 0) + angle(-45, 0, 0) ) ); assemblePiece(context, @@ -79,12 +79,12 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex cull(DOWN | NORTH | SOUTH), scale( pivot(16, 16, 16), - vec3(1, 1, MID_LENGTH / ALIGNED_LENGTH) + scale(1, 1, MID_LENGTH / ALIGNED_LENGTH) ), translate(0, 0, -MARGIN_ADJ), rotate( pivot(16, 16, 16), - vec3(-45, 0, 0) + angle(-45, 0, 0) ) ); assemblePiece(context, @@ -95,7 +95,7 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex slope(Direction.DOWN, (a, b) -> map(16 - MARGIN_ADJ, 16, MARGIN, 0, b)), rotate( pivot(16, 16, 16), - vec3(-45, 0, 0) + angle(-45, 0, 0) ) ); } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java index ec5a15c0e..ff45baf66 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java @@ -25,7 +25,7 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform if (cull.isCulled(context.source().lightFace())) { return; } - assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX / 16f, select.minY / 16f, select.minZ / 16f)); + assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ)); } public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform globalTransform, MutableVec3 offset, MutableAABB select, MutableCullFace cull, QuadTransform... transforms) { @@ -39,7 +39,7 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform if (cull.isCulled(context.source().lightFace())) { return; } - assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX / 16f, select.minY / 16f, select.minZ / 16f), transforms); + assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ), transforms); } public static void assembleQuad(CopycatRenderContext ctx) { diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java index d0a4d2f5a..e66f4a119 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java @@ -16,8 +16,8 @@ public static T transformVertices(QuadRotate self, T data, TextureAtlasSprit MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); - Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3Unscaled().subtract(self.pivot), self.rotation).add(self.pivot); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); + Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3().subtract(self.pivot), self.rotation).add(self.pivot); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); } return (T) vertexData; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java index fac6c9c00..160d3bfbd 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java @@ -15,7 +15,7 @@ public static T transformVertices(QuadScale self, T data, TextureAtlasSprite MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java index e89ee1d30..75c23e901 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java @@ -16,11 +16,11 @@ public static T transformVertices(QuadShear self, T data, TextureAtlasSprite MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); double shearAxis = mutableVertex.get(self.axis); double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); - mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis / 16 * amount); + mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis * amount); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java index ee81780de..fbf3bb0ed 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java @@ -15,7 +15,7 @@ public static T transformVertices(QuadTranslate self, T data, TextureAtlasSp MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); mutableVertex.x += self.x; mutableVertex.y += self.y; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java index 1c614a1f5..2369701e2 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java @@ -22,7 +22,7 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform if (cull.isCulled(quad.getDirection())) { continue; } - assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX / 16f, select.minY / 16f, select.minZ / 16f)); + assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ)); } } @@ -38,7 +38,7 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform if (cull.isCulled(quad.getDirection())) { continue; } - assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX / 16f, select.minY / 16f, select.minZ / 16f), transforms); + assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ), transforms); } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java index 08acc709b..e0b740599 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java @@ -14,8 +14,8 @@ public static T transformVertices(QuadRotate self, T data, TextureAtlasSprit MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); - Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3Unscaled().subtract(self.pivot), self.rotation).add(self.pivot); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); + Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3().subtract(self.pivot), self.rotation).add(self.pivot); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); } return (T) vertexData; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java index bf5c1ffcd..c9a969dd3 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java @@ -13,7 +13,7 @@ public static T transformVertices(QuadScale self, T data, TextureAtlasSprite MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java index 86f590c28..4aebd95d5 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java @@ -14,11 +14,11 @@ public static T transformVertices(QuadShear self, T data, TextureAtlasSprite MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); double shearAxis = mutableVertex.get(self.axis); double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); - mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis / 16 * amount); + mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis * amount); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java index 8cb9a2f41..6b0fdc4cf 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java @@ -13,7 +13,7 @@ public static T transformVertices(QuadTranslate self, T data, TextureAtlasSp MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x * 16, vertex.y * 16, vertex.z * 16)); + self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); mutableVertex.x += self.x; mutableVertex.y += self.y; From 6200d69b1b0bac6a04986d96645cc194615f89b0 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 17 Jun 2024 21:37:39 +0800 Subject: [PATCH 03/71] Implement some Vec3 methods in MutableVec3 --- .../base/model/assembly/MutableVec3.java | 86 ++++++++++++++++++- .../model/assembly/fabric/QuadRotateImpl.java | 4 +- .../model/assembly/fabric/QuadScaleImpl.java | 6 +- .../assembly/fabric/QuadTranslateImpl.java | 6 +- .../model/assembly/forge/QuadRotateImpl.java | 4 +- .../model/assembly/forge/QuadScaleImpl.java | 6 +- .../assembly/forge/QuadTranslateImpl.java | 6 +- 7 files changed, 90 insertions(+), 28 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java index e44b4f24f..860dd52ea 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java @@ -1,9 +1,11 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; -import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Position; +import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; -public class MutableVec3 implements GlobalTransform.Transformable { +public class MutableVec3 implements GlobalTransform.Transformable, Position { public double x; public double y; public double z; @@ -74,7 +76,7 @@ public MutableVec3 set(double x, double y, double z) { return this; } - public double get(Direction.Axis axis) { + public double get(Axis axis) { return switch (axis) { case X -> x; case Y -> y; @@ -82,7 +84,7 @@ public double get(Direction.Axis axis) { }; } - public MutableVec3 set(Direction.Axis axis, double value) { + public MutableVec3 set(Axis axis, double value) { switch (axis) { case X -> x = value; case Y -> y = value; @@ -91,6 +93,82 @@ public MutableVec3 set(Direction.Axis axis, double value) { return this; } + public boolean isZero() { + return x == 0 && y == 0 && z == 0; + } + + public MutableVec3 add(Position vec) { + return add(vec.x(), vec.y(), vec.z()); + } + + public MutableVec3 add(double x, double y, double z) { + return set(this.x + x, this.y + y, this.z + z); + } + + public MutableVec3 subtract(Position vec) { + return set(x - vec.x(), y - vec.y(), z - vec.z()); + } + + public MutableVec3 scale(double scale) { + return set(x * scale, y * scale, z * scale); + } + + public MutableVec3 multiply(Position vec) { + return set(x * vec.x(), y * vec.y(), z * vec.z()); + } + + public MutableVec3 rotate(Position rotationVec) { + return rotate(rotationVec.x(), rotationVec.y(), rotationVec.z()); + } + + public MutableVec3 rotate(double xRot, double yRot, double zRot) { + rotate(xRot, Axis.X); + rotate(yRot, Axis.Y); + rotate(zRot, Axis.Z); + return this; + } + + public MutableVec3 rotate(double deg, Axis axis) { + if (deg == 0) + return this; + if (this.isZero()) + return this; + + float angle = (float) (deg / 180f * Math.PI); + double sin = Mth.sin(angle); + double cos = Mth.cos(angle); + double x = this.x; + double y = this.y; + double z = this.z; + + if (axis == Axis.X){ + this.y = y * cos - z * sin; + this.z = z * cos + y * sin; + } else if (axis == Axis.Y){ + this.x = x * cos + z * sin; + this.z = z * cos - x * sin; + } else if (axis == Axis.Z){ + this.x = x * cos - y * sin; + this.y = y * cos + x * sin; + } + return this; + } + + @Override + public double x() { + return x; + } + + @Override + public double y() { + return y; + } + + @Override + public double z() { + return z; + } + /** * Marker subclass for when a Vec3 is used as a pivot point */ diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java index e66f4a119..5abdd819d 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java @@ -17,8 +17,8 @@ public static T transformVertices(QuadRotate self, T data, TextureAtlasSprit for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3().subtract(self.pivot), self.rotation).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); + mutableVertex.subtract(self.pivot).rotate(self.rotation).add(self.pivot); + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java index 160d3bfbd..a0569f9ac 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java @@ -16,11 +16,7 @@ public static T transformVertices(QuadScale self, T data, TextureAtlasSprite for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; - mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; - mutableVertex.z = (mutableVertex.z - self.pivot.z) * self.scale.z + self.pivot.z; - + mutableVertex.subtract(self.pivot).multiply(self.scale).add(self.pivot); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java index fbf3bb0ed..96d619f5b 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java @@ -16,11 +16,7 @@ public static T transformVertices(QuadTranslate self, T data, TextureAtlasSp for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - mutableVertex.x += self.x; - mutableVertex.y += self.y; - mutableVertex.z += self.z; - + mutableVertex.add(self.x, self.y, self.z); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java index e0b740599..f08576653 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java @@ -15,8 +15,8 @@ public static T transformVertices(QuadRotate self, T data, TextureAtlasSprit for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - Vec3 rotated = VecHelper.rotate(mutableVertex.toVec3().subtract(self.pivot), self.rotation).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex.set(rotated.x, rotated.y, rotated.z)).toVec3()); + mutableVertex.subtract(self.pivot).rotate(self.rotation).add(self.pivot); + BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java index c9a969dd3..8abd66f7c 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java @@ -14,11 +14,7 @@ public static T transformVertices(QuadScale self, T data, TextureAtlasSprite for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - mutableVertex.x = (mutableVertex.x - self.pivot.x) * self.scale.x + self.pivot.x; - mutableVertex.y = (mutableVertex.y - self.pivot.y) * self.scale.y + self.pivot.y; - mutableVertex.z = (mutableVertex.z - self.pivot.z) * self.scale.z + self.pivot.z; - + mutableVertex.subtract(self.pivot).multiply(self.scale).add(self.pivot); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java index 6b0fdc4cf..bcd7ff714 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java @@ -14,11 +14,7 @@ public static T transformVertices(QuadTranslate self, T data, TextureAtlasSp for (int i = 0; i < 4; i++) { Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - mutableVertex.x += self.x; - mutableVertex.y += self.y; - mutableVertex.z += self.z; - + mutableVertex.add(self.x, self.y, self.z); BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); } return (T) vertexData; From 543c28a0d60046f3d221a8630ea6eabf2b464b9f Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Mon, 17 Jun 2024 14:44:42 +0100 Subject: [PATCH 04/71] Add shape for slop --- .../com/copycatsplus/copycats/CCShapes.java | 37 +++++++++++++++++++ .../copycat/slope/CopycatSlopeBlock.java | 4 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java index 63e0f2c9a..afb3f431e 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java @@ -137,6 +137,43 @@ public class CCShapes { .add(0, 0, 8, 8, 8, 16) .add(8, 0, 8, 16, 16, 16) .forDirectional(Direction.NORTH); + public static final VoxelShaper SLOPE = shape(Shapes.empty()).build((voxelShape, direction) -> { + VoxelShape shape = Shapes.empty(); + shape = Shapes.join(shape, Shapes.box(0, 0, 0, 1, 0.03125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.0625, 0, 0.9375, 0.09375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.125, 0, 0.875, 0.15625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.1875, 0, 0.8125, 0.21875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.25, 0, 0.75, 0.28125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.3125, 0, 0.6875, 0.34375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.375, 0, 0.625, 0.40625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.4375, 0, 0.5625, 0.46875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.8125, 0, 0.1875, 0.84375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.5, 0, 0.5, 0.53125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.5625, 0, 0.4375, 0.59375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.625, 0, 0.375, 0.65625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.6875, 0, 0.3125, 0.71875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.75, 0, 0.25, 0.78125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.9375, 0, 0.0625, 0.96875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.875, 0, 0.125, 0.90625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.65625, 0, 0.34375, 0.6875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.03125, 0, 0.96875, 0.0625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.09375, 0, 0.90625, 0.125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.15625, 0, 0.84375, 0.1875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.21875, 0, 0.78125, 0.25, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.28125, 0, 0.71875, 0.3125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.34375, 0, 0.65625, 0.375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.40625, 0, 0.59375, 0.4375, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.46875, 0, 0.53125, 0.5, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.84375, 0, 0.15625, 0.875, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.53125, 0, 0.46875, 0.5625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.59375, 0, 0.40625, 0.625, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.71875, 0, 0.28125, 0.75, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.78125, 0, 0.21875, 0.8125, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.96875, 0, 0.03125, 1, 1), BooleanOp.OR); + shape = Shapes.join(shape, Shapes.box(0, 0.90625, 0, 0.09375, 0.9375, 1), BooleanOp.OR); + + return shape(shape).forDirectional(Direction.WEST); + }, Direction.SOUTH); private static Builder shape(VoxelShape shape) { return new Builder(shape); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java index 236a34494..9ba46a005 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.slope; import com.copycatsplus.copycats.CCBlocks; +import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.IStateType; import com.simibubi.create.content.equipment.extendoGrip.ExtendoGripItem; @@ -34,6 +35,7 @@ import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; @@ -163,7 +165,7 @@ protected void createBlockStateDefinition(StateDefinition.Builder Date: Mon, 17 Jun 2024 23:51:58 +0800 Subject: [PATCH 05/71] Optimize rendering by using mutable structures and extracting global transform ops --- .../base/model/assembly/Assembler.java | 7 ++ .../base/model/assembly/MutableQuad.java | 71 +++++++++++++++++++ .../base/model/assembly/MutableUV.java | 20 ++++++ .../base/model/assembly/MutableVec3.java | 4 ++ .../base/model/assembly/MutableVertex.java | 16 +++++ .../base/model/assembly/QuadRotate.java | 25 ------- .../base/model/assembly/QuadScale.java | 25 ------- .../base/model/assembly/QuadShear.java | 28 -------- .../base/model/assembly/QuadTransform.java | 9 --- .../base/model/assembly/QuadTranslate.java | 26 ------- .../model/assembly/TrackingQuadTransform.java | 64 ----------------- .../base/model/assembly/quad/QuadRotate.java | 15 ++++ .../base/model/assembly/quad/QuadScale.java | 15 ++++ .../base/model/assembly/quad/QuadShear.java | 21 ++++++ .../model/assembly/{ => quad}/QuadSlope.java | 49 ++++++------- .../model/assembly/quad/QuadTransform.java | 9 +++ .../model/assembly/quad/QuadTranslate.java | 14 ++++ .../model/assembly/{ => quad}/UVHelper.java | 2 +- .../slope/CopycatSlopeEnhancedModel.java | 2 +- .../model/assembly/fabric/AssemblerImpl.java | 38 +++++++--- .../model/assembly/fabric/QuadRotateImpl.java | 25 ------- .../model/assembly/fabric/QuadScaleImpl.java | 24 ------- .../model/assembly/fabric/QuadShearImpl.java | 29 -------- .../assembly/fabric/QuadTranslateImpl.java | 24 ------- .../{ => quad}/fabric/UVHelperImpl.java | 4 +- .../model/assembly/forge/AssemblerImpl.java | 39 +++++++--- .../model/assembly/forge/QuadRotateImpl.java | 23 ------ .../model/assembly/forge/QuadScaleImpl.java | 22 ------ .../model/assembly/forge/QuadShearImpl.java | 27 ------- .../assembly/forge/QuadTranslateImpl.java | 22 ------ .../{ => quad}/forge/UVHelperImpl.java | 4 +- 31 files changed, 279 insertions(+), 424 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableUV.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVertex.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTransform.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadRotate.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadScale.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadShear.java rename common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/{ => quad}/QuadSlope.java (57%) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTransform.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTranslate.java rename common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/{ => quad}/UVHelper.java (97%) delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java rename fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/{ => quad}/fabric/UVHelperImpl.java (98%) delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java rename forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/{ => quad}/forge/UVHelperImpl.java (98%) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index c8e6560ae..0ce6bfb78 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -1,11 +1,13 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.*; import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.core.Direction; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Objects; public class Assembler { @@ -100,6 +102,11 @@ public static void assembleQuad(Source src, Destination de } + @ExpectPlatform + public static MutableQuad getMutableQuad(T vertexData) { + return null; + } + public static MutableCullFace cull(int mask) { return new MutableCullFace(mask); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java new file mode 100644 index 000000000..2637888b8 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java @@ -0,0 +1,71 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +import java.util.ArrayList; +import java.util.List; + +public class MutableQuad implements GlobalTransform.Transformable { + public List vertices; + List mutations = new ArrayList<>(); + + public MutableQuad(List vertices) { + this.vertices = vertices; + } + + public MutableQuad mutate() { + for (Mutation mutation : mutations) { + for (MutableVertex vertex : vertices) { + mutation.mutate(vertex.xyz); + } + } + return this; + } + + public MutableQuad undoMutate() { + for (int i = mutations.size() - 1; i >= 0; i--) { + Mutation mutation = mutations.get(i); + for (MutableVertex vertex : vertices) { + mutation.undoMutate(vertex.xyz); + } + } + return this; + } + + @Override + public MutableQuad rotateX(int angle) { + mutations.add(new Mutation(Mutation.MutationType.ROTATE_X, angle)); + return this; + } + + @Override + public MutableQuad rotateY(int angle) { + mutations.add(new Mutation(Mutation.MutationType.ROTATE_Y, angle)); + return this; + } + + @Override + public MutableQuad rotateZ(int angle) { + mutations.add(new Mutation(Mutation.MutationType.ROTATE_Z, angle)); + return this; + } + + @Override + public MutableQuad flipX(boolean flip) { + if (!flip) return this; + mutations.add(new Mutation(Mutation.MutationType.MIRROR, 0)); + return this; + } + + @Override + public MutableQuad flipY(boolean flip) { + if (!flip) return this; + mutations.add(new Mutation(Mutation.MutationType.MIRROR, 1)); + return this; + } + + @Override + public MutableQuad flipZ(boolean flip) { + if (!flip) return this; + mutations.add(new Mutation(Mutation.MutationType.MIRROR, 2)); + return this; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableUV.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableUV.java new file mode 100644 index 000000000..49afb7f20 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableUV.java @@ -0,0 +1,20 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +public class MutableUV { + public float u; + public float v; + + public MutableUV(float u, float v) { + set(u, v); + } + + public MutableUV set(float u, float v) { + this.u = u; + this.v = v; + return this; + } + + public boolean isZero() { + return u == 0 && v == 0; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java index 860dd52ea..0074581bd 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java @@ -10,6 +10,10 @@ public class MutableVec3 implements GlobalTransform.Transformable, public double y; public double z; + public MutableVec3(Position position) { + this(position.x(), position.y(), position.z()); + } + public MutableVec3(double x, double y, double z) { set(x, y, z); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVertex.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVertex.java new file mode 100644 index 000000000..3fb3778d6 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVertex.java @@ -0,0 +1,16 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly; + +public class MutableVertex { + public MutableVec3 xyz; + public MutableUV uv; + + public MutableVertex(MutableVec3 xyz, MutableUV uv) { + set(xyz, uv); + } + + public MutableVertex set(MutableVec3 xyz, MutableUV uv) { + this.xyz = xyz; + this.uv = uv; + return this; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java deleted file mode 100644 index 281bbcc56..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadRotate.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadRotate extends TrackingQuadTransform { - public final Vec3 pivot; - public final Vec3 rotation; - - public QuadRotate(MutableVec3.AsPivot pivot, MutableVec3.AsAngle rotation) { - this.pivot = pivot.toVec3(); - this.rotation = rotation.toVec3(); - } - - @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - return transformVertices(this, vertexData, sprite); - } - - @ExpectPlatform - public static T transformVertices(QuadRotate self, T vertexData, TextureAtlasSprite sprite) { - return null; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java deleted file mode 100644 index 96f49dbc5..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadScale.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadScale extends TrackingQuadTransform { - public final Vec3 pivot; - public final Vec3 scale; - - public QuadScale(MutableVec3.AsPivot pivot, MutableVec3.AsScale scale) { - this.pivot = pivot.toVec3(); - this.scale = scale.toVec3(); - } - - @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - return transformVertices(this, vertexData, sprite); - } - - @ExpectPlatform - public static T transformVertices(QuadScale self, T vertexData, TextureAtlasSprite sprite) { - return null; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java deleted file mode 100644 index a216d6fc2..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadShear.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; - -public class QuadShear extends TrackingQuadTransform { - public final Axis axis; - public final Direction direction; - public final double amount; - - public QuadShear(Axis axis, Direction direction, double amount) { - this.axis = axis; - this.direction = direction; - this.amount = amount; - } - - @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - return transformVertices(this, vertexData, sprite); - } - - @ExpectPlatform - public static T transformVertices(QuadShear self, T vertexData, TextureAtlasSprite sprite) { - return null; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTransform.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTransform.java deleted file mode 100644 index d9146c043..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTransform.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; - -import java.util.List; - -public interface QuadTransform extends GlobalTransform.Transformable { - T transformVertices(T vertexData, TextureAtlasSprite sprite); -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java deleted file mode 100644 index 91921714f..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadTranslate.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; - -public class QuadTranslate extends TrackingQuadTransform { - public final double x; - public final double y; - public final double z; - - public QuadTranslate(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - return transformVertices(this, vertexData, sprite); - } - - @ExpectPlatform - public static T transformVertices(QuadTranslate self, T vertexData, TextureAtlasSprite sprite) { - return null; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java deleted file mode 100644 index 824288b19..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/TrackingQuadTransform.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.Mutation.MutationType; - -import java.util.ArrayList; -import java.util.List; - -public abstract class TrackingQuadTransform implements QuadTransform { - List mutations = new ArrayList<>(2); - - public MutableVec3 mutate(MutableVec3 vec3) { - for (Mutation mutation : mutations) { - mutation.mutate(vec3); - } - return vec3; - } - - public MutableVec3 undoMutate(MutableVec3 vec3) { - for (int i = mutations.size() - 1; i >= 0; i--) { - Mutation mutation = mutations.get(i); - mutation.undoMutate(vec3); - } - return vec3; - } - - @Override - public QuadTransform rotateX(int angle) { - mutations.add(new Mutation(MutationType.ROTATE_X, angle)); - return this; - } - - @Override - public QuadTransform rotateY(int angle) { - mutations.add(new Mutation(MutationType.ROTATE_Y, angle)); - return this; - } - - @Override - public QuadTransform rotateZ(int angle) { - mutations.add(new Mutation(MutationType.ROTATE_Z, angle)); - return this; - } - - @Override - public QuadTransform flipX(boolean flip) { - if (!flip) return this; - mutations.add(new Mutation(MutationType.MIRROR, 0)); - return this; - } - - @Override - public QuadTransform flipY(boolean flip) { - if (!flip) return this; - mutations.add(new Mutation(MutationType.MIRROR, 1)); - return this; - } - - @Override - public QuadTransform flipZ(boolean flip) { - if (!flip) return this; - mutations.add(new Mutation(MutationType.MIRROR, 2)); - return this; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadRotate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadRotate.java new file mode 100644 index 000000000..e313fde24 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadRotate.java @@ -0,0 +1,15 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + +public record QuadRotate(MutableVec3.AsPivot pivot, MutableVec3.AsAngle rotation) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + for (int i = 0; i < 4; i++) { + quad.vertices.get(i).xyz.subtract(this.pivot).rotate(this.rotation).add(this.pivot); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadScale.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadScale.java new file mode 100644 index 000000000..275be3297 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadScale.java @@ -0,0 +1,15 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + +public record QuadScale(MutableVec3.AsPivot pivot, MutableVec3.AsScale scale) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + for (int i = 0; i < 4; i++) { + quad.vertices.get(i).xyz.subtract(this.pivot).multiply(this.scale).add(this.pivot); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadShear.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadShear.java new file mode 100644 index 000000000..a9779c284 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadShear.java @@ -0,0 +1,21 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; + +public record QuadShear(Axis axis, Direction direction, double amount) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + for (int i = 0; i < 4; i++) { + MutableVec3 vertex = quad.vertices.get(i).xyz; + + double shearAxis = vertex.get(this.axis); + double amount = this.amount * (this.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); + vertex.set(this.direction.getAxis(), vertex.get(this.direction.getAxis()) + shearAxis * amount); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java similarity index 57% rename from common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java rename to common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java index dc1bbdab8..0c6b8575f 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/QuadSlope.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java @@ -1,39 +1,32 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; -public class QuadSlope extends TrackingQuadTransform { - - public final Direction face; - public final QuadSlopeFunction func; - - public QuadSlope(Direction face, QuadSlopeFunction func) { - this.face = face; - this.func = func; - } +public record QuadSlope(Direction face, QuadSlopeFunction func) implements QuadTransform { @Override - public T transformVertices(T vertexData, TextureAtlasSprite sprite) { - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - return (T) UVHelper.mapWithUV(vertexData, sprite, (vertex, i) -> { - this.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + for (int i = 0; i < 4; i++) { + MutableVec3 vertex = quad.vertices.get(i).xyz; double a; double b; switch (this.face.getAxis()) { case X: - a = mutableVertex.y; - b = mutableVertex.z; + a = vertex.y; + b = vertex.z; break; case Y: - a = mutableVertex.x; - b = mutableVertex.z; + a = vertex.x; + b = vertex.z; break; case Z: - a = mutableVertex.x; - b = mutableVertex.y; + a = vertex.x; + b = vertex.y; break; default: throw new RuntimeException("Unexpected value: " + this.face.getAxis()); @@ -44,31 +37,29 @@ public T transformVertices(T vertexData, TextureAtlasSprite sprite) { switch (this.face.getAxis()) { case X: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.x *= output; + vertex.x *= output; } else { - mutableVertex.x = 1 - output * (1 - mutableVertex.x); + vertex.x = 1 - output * (1 - vertex.x); } break; case Y: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.y *= output; + vertex.y *= output; } else { - mutableVertex.y = 1 - output * (1 - mutableVertex.y); + vertex.y = 1 - output * (1 - vertex.y); } break; case Z: if (this.face.getAxisDirection() == Direction.AxisDirection.POSITIVE) { - mutableVertex.z *= output; + vertex.z *= output; } else { - mutableVertex.z = 1 - output * (1 - mutableVertex.z); + vertex.z = 1 - output * (1 - vertex.z); } break; default: throw new RuntimeException("Unexpected value: " + this.face.getAxis()); } - - return this.mutate(mutableVertex).toVec3(); - }); + } } public static double map(double fromStart, double fromEnd, double toStart, double toEnd, double value) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTransform.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTransform.java new file mode 100644 index 000000000..664a3da8c --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTransform.java @@ -0,0 +1,9 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + + +public interface QuadTransform { + void transformVertices(MutableQuad quad, TextureAtlasSprite sprite); +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTranslate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTranslate.java new file mode 100644 index 000000000..29120addd --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadTranslate.java @@ -0,0 +1,14 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + +public record QuadTranslate(double x, double y, double z) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + for (int i = 0; i < 4; i++) { + quad.vertices.get(i).xyz.add(this.x, this.y, this.z); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java similarity index 97% rename from common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java rename to common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java index 59c055c66..86e81f1bc 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/UVHelper.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java @@ -1,4 +1,4 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly; +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.client.renderer.texture.TextureAtlasSprite; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java index 206edb7e1..64a4fe95a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java @@ -8,7 +8,7 @@ import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadSlope.map; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.QuadSlope.map; public class CopycatSlopeEnhancedModel implements SimpleCopycatPart { diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java index ff45baf66..3ad81c798 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java @@ -1,7 +1,9 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; import com.copycatsplus.copycats.content.copycat.base.model.assembly.*; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.QuadTransform; import com.simibubi.create.foundation.model.BakedModelHelper; +import com.simibubi.create.foundation.model.BakedQuadHelper; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.model.SpriteFinder; @@ -11,6 +13,9 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import java.util.ArrayList; +import java.util.List; + import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; public class AssemblerImpl { @@ -25,7 +30,7 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform if (cull.isCulled(context.source().lightFace())) { return; } - assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ)); + assembleQuad(context.source(), context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ)); } public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform globalTransform, MutableVec3 offset, MutableAABB select, MutableCullFace cull, QuadTransform... transforms) { @@ -33,13 +38,10 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform globalTransform.apply(select); globalTransform.apply(offset); globalTransform.apply(cull); - for (QuadTransform transform : transforms) { - globalTransform.apply(transform); - } if (cull.isCulled(context.source().lightFace())) { return; } - assembleQuad(context, select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ), transforms); + assembleQuad(context.source(), context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ), globalTransform, transforms); } public static void assembleQuad(CopycatRenderContext ctx) { @@ -59,7 +61,7 @@ public static void assembleQuad(CopycatRenderContext ctx, AABB crop, Vec3 public static void assembleQuad(CopycatRenderContext ctx, AABB crop, Vec3 move, QuadTransform... transforms) { CopycatRenderContextFabric context = (CopycatRenderContextFabric) ctx; - assembleQuad(context.source(), context.destination(), crop, move, transforms); + assembleQuad(context.source(), context.destination(), crop, move, GlobalTransform.IDENTITY, transforms); } @@ -69,13 +71,33 @@ public static dest.emit(); } - public static void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, QuadTransform... transforms) { + public static void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, GlobalTransform globalTransform, QuadTransform... transforms) { dest.copyFrom(src); TextureAtlasSprite sprite = spriteFinder.find(src); BakedModelHelper.cropAndMove(dest, sprite, crop, move); + MutableQuad mutableQuad = getMutableQuad(dest); + globalTransform.apply(mutableQuad); + mutableQuad.undoMutate(); for (QuadTransform transform : transforms) { - src = transform.transformVertices(src, sprite); + transform.transformVertices(mutableQuad, sprite); + } + mutableQuad.mutate(); + for (int i = 0; i < 4; i++) { + BakedQuadHelper.setXYZ(dest, i, mutableQuad.vertices.get(i).xyz.toVec3()); + dest.uv(i, mutableQuad.vertices.get(i).uv.u, mutableQuad.vertices.get(i).uv.v); + } + dest.emit(); + } + + public static MutableQuad getMutableQuad(T data) { + MutableQuadView vertexData = (MutableQuadView) data; + List vertices = new ArrayList<>(4); + for (int i = 0; i < 4; i++) { + MutableVec3 xyz = new MutableVec3(vertexData.x(i), vertexData.y(i), vertexData.z(i)); + MutableUV uv = new MutableUV(vertexData.u(i), vertexData.v(i)); + vertices.add(new MutableVertex(xyz, uv)); } + return new MutableQuad(vertices); } public static class CopycatRenderContextFabric extends CopycatRenderContext { diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java deleted file mode 100644 index 5abdd819d..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadRotateImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotate; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import com.simibubi.create.foundation.utility.VecHelper; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadRotateImpl { - - @SuppressWarnings("unchecked") - public static T transformVertices(QuadRotate self, T data, TextureAtlasSprite sprite) { - MutableQuadView vertexData = (MutableQuadView) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.subtract(self.pivot).rotate(self.rotation).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java deleted file mode 100644 index a0569f9ac..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadScaleImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadScale; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadScaleImpl { - - @SuppressWarnings("unchecked") - public static T transformVertices(QuadScale self, T data, TextureAtlasSprite sprite) { - MutableQuadView vertexData = (MutableQuadView) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.subtract(self.pivot).multiply(self.scale).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java deleted file mode 100644 index 75c23e901..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadShearImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadShear; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.Direction; -import net.minecraft.world.phys.Vec3; - -public class QuadShearImpl { - - @SuppressWarnings("unchecked") - public static T transformVertices(QuadShear self, T data, TextureAtlasSprite sprite) { - MutableQuadView vertexData = (MutableQuadView) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - double shearAxis = mutableVertex.get(self.axis); - double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); - mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis * amount); - - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java deleted file mode 100644 index 96d619f5b..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/QuadTranslateImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadTranslate; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadTranslateImpl { - - @SuppressWarnings("unchecked") - public static T transformVertices(QuadTranslate self, T data, TextureAtlasSprite sprite) { - MutableQuadView vertexData = (MutableQuadView) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.add(self.x, self.y, self.z); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java similarity index 98% rename from fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java rename to fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java index 9c0c0f915..eaf2ee56f 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/UVHelperImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java @@ -1,6 +1,6 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric; +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.fabric; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.UVHelper; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.UVHelper; import com.simibubi.create.foundation.model.BakedQuadHelper; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.minecraft.client.renderer.texture.TextureAtlasSprite; diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java index 2369701e2..37a3ced40 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java @@ -1,12 +1,14 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; import com.copycatsplus.copycats.content.copycat.base.model.assembly.*; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.QuadTransform; import com.simibubi.create.foundation.model.BakedModelHelper; import com.simibubi.create.foundation.model.BakedQuadHelper; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import java.util.ArrayList; import java.util.List; import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; @@ -18,11 +20,13 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform globalTransform.apply(select); globalTransform.apply(offset); globalTransform.apply(cull); + AABB aabb = select.toAABB(); + Vec3 vec3 = offset.toVec3().subtract(select.minX, select.minY, select.minZ); for (BakedQuad quad : context.source()) { if (cull.isCulled(quad.getDirection())) { continue; } - assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ)); + assembleQuad(quad, context.destination(), aabb, vec3); } } @@ -31,14 +35,13 @@ public static void assemblePiece(CopycatRenderContext ctx, GlobalTransform globalTransform.apply(select); globalTransform.apply(offset); globalTransform.apply(cull); - for (QuadTransform transform : transforms) { - globalTransform.apply(transform); - } + AABB aabb = select.toAABB(); + Vec3 vec3 = offset.toVec3().subtract(select.minX, select.minY, select.minZ); for (BakedQuad quad : context.source()) { if (cull.isCulled(quad.getDirection())) { continue; } - assembleQuad(quad, context.destination(), select.toAABB(), offset.toVec3().subtract(select.minX, select.minY, select.minZ), transforms); + assembleQuad(quad, context.destination(), aabb, vec3, globalTransform, transforms); } } @@ -63,7 +66,7 @@ public static void assembleQuad(CopycatRenderContext ctx, AABB crop, Vec3 public static void assembleQuad(CopycatRenderContext ctx, AABB crop, Vec3 move, QuadTransform... transforms) { CopycatRenderContextForge context = (CopycatRenderContextForge) ctx; for (BakedQuad quad : context.source()) { - assembleQuad(quad, context.destination(), crop, move, transforms); + assembleQuad(quad, context.destination(), crop, move, GlobalTransform.IDENTITY, transforms); } } @@ -73,14 +76,34 @@ public static > vo BakedModelHelper.cropAndMove(src.getVertices(), src.getSprite(), crop, move))); } - public static > void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, QuadTransform... transforms) { + public static > void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, GlobalTransform globalTransform, QuadTransform... transforms) { int[] vertices = BakedModelHelper.cropAndMove(src.getVertices(), src.getSprite(), crop, move); + MutableQuad mutableQuad = getMutableQuad(vertices); + globalTransform.apply(mutableQuad); + mutableQuad.undoMutate(); for (QuadTransform transform : transforms) { - vertices = transform.transformVertices(vertices, src.getSprite()); + transform.transformVertices(mutableQuad, src.getSprite()); + } + mutableQuad.mutate(); + for (int i = 0; i < 4; i++) { + BakedQuadHelper.setXYZ(vertices, i, mutableQuad.vertices.get(i).xyz.toVec3()); + BakedQuadHelper.setU(vertices, i, mutableQuad.vertices.get(i).uv.u); + BakedQuadHelper.setV(vertices, i, mutableQuad.vertices.get(i).uv.v); } dest.add(BakedQuadHelper.cloneWithCustomGeometry(src, vertices)); } + public static MutableQuad getMutableQuad(T data) { + int[] vertexData = (int[]) data; + List vertices = new ArrayList<>(4); + for (int i = 0; i < 4; i++) { + MutableVec3 xyz = new MutableVec3(BakedQuadHelper.getXYZ(vertexData, i)); + MutableUV uv = new MutableUV(BakedQuadHelper.getU(vertexData, i), BakedQuadHelper.getV(vertexData, i)); + vertices.add(new MutableVertex(xyz, uv)); + } + return new MutableQuad(vertices); + } + public static class CopycatRenderContextForge extends CopycatRenderContext, List> { public CopycatRenderContextForge(List source, List destination) { super(source, destination); diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java deleted file mode 100644 index f08576653..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadRotateImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadRotate; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import com.simibubi.create.foundation.utility.VecHelper; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadRotateImpl { - - public static T transformVertices(QuadRotate self, T data, TextureAtlasSprite sprite) { - int[] vertexData = (int[]) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.subtract(self.pivot).rotate(self.rotation).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java deleted file mode 100644 index 8abd66f7c..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadScaleImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadScale; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadScaleImpl { - - public static T transformVertices(QuadScale self, T data, TextureAtlasSprite sprite) { - int[] vertexData = (int[]) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.subtract(self.pivot).multiply(self.scale).add(self.pivot); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java deleted file mode 100644 index 4aebd95d5..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadShearImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadShear; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.Direction; -import net.minecraft.world.phys.Vec3; - -public class QuadShearImpl { - - public static T transformVertices(QuadShear self, T data, TextureAtlasSprite sprite) { - int[] vertexData = (int[]) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - - double shearAxis = mutableVertex.get(self.axis); - double amount = self.amount * (self.direction.getAxisDirection() == Direction.AxisDirection.POSITIVE ? 1 : -1); - mutableVertex.set(self.direction.getAxis(), mutableVertex.get(self.direction.getAxis()) + shearAxis * amount); - - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java deleted file mode 100644 index bcd7ff714..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/QuadTranslateImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.QuadTranslate; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class QuadTranslateImpl { - - public static T transformVertices(QuadTranslate self, T data, TextureAtlasSprite sprite) { - int[] vertexData = (int[]) data; - MutableVec3 mutableVertex = new MutableVec3(0, 0, 0); - for (int i = 0; i < 4; i++) { - Vec3 vertex = BakedQuadHelper.getXYZ(vertexData, i); - self.undoMutate(mutableVertex.set(vertex.x, vertex.y, vertex.z)); - mutableVertex.add(self.x, self.y, self.z); - BakedQuadHelper.setXYZ(vertexData, i, self.mutate(mutableVertex).toVec3()); - } - return (T) vertexData; - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java similarity index 98% rename from forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java rename to forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java index 3dcec364f..38f2a42df 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/UVHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java @@ -1,6 +1,6 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.forge; +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.forge; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.UVHelper; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.UVHelper; import com.simibubi.create.foundation.model.BakedQuadHelper; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.world.phys.Vec3; From 62473d661f239b0313de947cd306c3aaad5fb394 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 18 Jun 2024 11:34:45 +0800 Subject: [PATCH 06/71] Move UVHelper to QuadUVUpdate --- .../base/model/assembly/Assembler.java | 4 + .../base/model/assembly/MutableVec3.java | 79 ++++++++++++++++- .../model/assembly/quad/QuadUVUpdate.java | 87 +++++++++++++++++++ .../base/model/assembly/quad/UVHelper.java | 17 ---- .../slope/CopycatSlopeEnhancedModel.java | 10 +-- .../copycat/slope/CopycatSlopeModel.java | 2 +- .../assembly/quad/fabric/UVHelperImpl.java | 78 ----------------- .../assembly/quad/forge/UVHelperImpl.java | 80 ----------------- 8 files changed, 173 insertions(+), 184 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadUVUpdate.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index 0ce6bfb78..1c7ec2cd4 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -151,6 +151,10 @@ public static QuadShear shear(Direction.Axis axis, Direction direction, double a return new QuadShear(axis, direction, amount / 16); } + public static QuadUVUpdate updateUV(QuadTransform... transforms) { + return new QuadUVUpdate(transforms); + } + public static class CopycatRenderContext { private final Source source; private final Destination destination; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java index 0074581bd..83da545ca 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableVec3.java @@ -145,19 +145,92 @@ public MutableVec3 rotate(double deg, Axis axis) { double y = this.y; double z = this.z; - if (axis == Axis.X){ + if (axis == Axis.X) { this.y = y * cos - z * sin; this.z = z * cos + y * sin; - } else if (axis == Axis.Y){ + } else if (axis == Axis.Y) { this.x = x * cos + z * sin; this.z = z * cos - x * sin; - } else if (axis == Axis.Z){ + } else if (axis == Axis.Z) { this.x = x * cos - y * sin; this.y = y * cos + x * sin; } return this; } + public double dot(Position vec) { + return this.x * vec.x() + this.y * vec.y() + this.z * vec.z(); + } + + /** + * Returns a new vector with the result of this vector x the specified vector. + */ + public MutableVec3 cross(Position vec) { + return set(this.y * vec.z() - this.z * vec.y(), this.z * vec.x() - this.x * vec.z(), this.x * vec.y() - this.y * vec.x()); + } + + + /** + * Euclidean distance between this and the specified vector, returned as double. + */ + public double distanceTo(Position vec) { + double d = vec.x() - this.x; + double e = vec.y() - this.y; + double f = vec.z() - this.z; + return Math.sqrt(d * d + e * e + f * f); + } + + /** + * The square of the Euclidean distance between this and the specified vector. + */ + public double distanceToSqr(Position vec) { + double d = vec.x() - this.x; + double e = vec.y() - this.y; + double f = vec.z() - this.z; + return d * d + e * e + f * f; + } + + public double distanceToSqr(double x, double y, double z) { + double d = x - this.x; + double e = y - this.y; + double f = z - this.z; + return d * d + e * e + f * f; + } + + /** + * Returns the length of the vector. + */ + public double length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + + public double lengthSqr() { + return this.x * this.x + this.y * this.y + this.z * this.z; + } + + public double horizontalDistance() { + return Math.sqrt(this.x * this.x + this.z * this.z); + } + + public double horizontalDistanceSqr() { + return this.x * this.x + this.z * this.z; + } + + /** + * Normalizes the vector to a length of 1 (except if it is the zero vector) + */ + public MutableVec3 normalize() { + double d = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + if (d < 1.0E-4) { + return set(0, 0, 0); + } + return set(this.x / d, this.y / d, this.z / d); + } + + public MutableVec3 copy() { + return new MutableVec3(x, y, z); + } + @Override public double x() { return x; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadUVUpdate.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadUVUpdate.java new file mode 100644 index 000000000..05cdb3814 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadUVUpdate.java @@ -0,0 +1,87 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; + +import java.util.List; + +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU; +import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV; + +public record QuadUVUpdate(QuadTransform... transforms) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + List prevXYZ = List.of( + quad.vertices.get(0).xyz.copy(), + quad.vertices.get(1).xyz.copy(), + quad.vertices.get(2).xyz.copy(), + quad.vertices.get(3).xyz.copy() + ); + for (QuadTransform transform : transforms) { + transform.transformVertices(quad, sprite); + } + updateUV(quad, sprite, prevXYZ); + } + + public static void updateUV(MutableQuad quad, TextureAtlasSprite sprite, List prevXYZ) { + MutableVec3 xyz0 = prevXYZ.get(0); + MutableVec3 xyz1 = prevXYZ.get(1); + MutableVec3 xyz2 = prevXYZ.get(2); + MutableVec3 xyz3 = prevXYZ.get(3); + + MutableVec3 uAxis = xyz3.copy().add(xyz2) + .scale(.5); + MutableVec3 vAxis = xyz1.copy().add(xyz2) + .scale(.5); + MutableVec3 center = xyz3.copy().add(xyz2) + .add(xyz0) + .add(xyz1) + .scale(.25); + + float u0 = quad.vertices.get(0).uv.u; + float u3 = quad.vertices.get(3).uv.u; + float v0 = quad.vertices.get(0).uv.v; + float v1 = quad.vertices.get(1).uv.v; + + float uScale = (float) Math + .round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0)); + float vScale = (float) Math + .round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0)); + + if (uScale == 0) { + float v3 = quad.vertices.get(3).uv.v; + float u1 = quad.vertices.get(1).uv.u; + uAxis = xyz1.copy().add(xyz2) + .scale(.5); + vAxis = xyz3.copy().add(xyz2) + .scale(.5); + uScale = (float) Math + .round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0)); + vScale = (float) Math + .round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0)); + + } + + uAxis = uAxis.subtract(center) + .normalize(); + vAxis = vAxis.subtract(center) + .normalize(); + + for (int vertex = 0; vertex < 4; vertex++) { + MutableVec3 xyz = prevXYZ.get(vertex); + MutableVec3 newXyz = quad.vertices.get(vertex).xyz; + MutableVec3 diff = newXyz.copy().subtract(xyz); + + if (diff.lengthSqr() > 0) { + float u = quad.vertices.get(vertex).uv.u; + float v = quad.vertices.get(vertex).uv.v; + float uDiff = (float) uAxis.dot(diff) * uScale; + float vDiff = (float) vAxis.dot(diff) * vScale; + quad.vertices.get(vertex).uv.u = sprite.getU(getUnInterpolatedU(sprite, u) + uDiff); + quad.vertices.get(vertex).uv.v = sprite.getV(getUnInterpolatedV(sprite, v) + vDiff); + } + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java deleted file mode 100644 index 86e81f1bc..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/UVHelper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; - -import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -public class UVHelper { - @ExpectPlatform - public static T mapWithUV(T vertexData, TextureAtlasSprite sprite, QuadVertexMapper mapper) { - return null; - } - - @FunctionalInterface - public interface QuadVertexMapper { - Vec3 map(Vec3 vertex, int vertexIndex); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java index 64a4fe95a..23e182395 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java @@ -29,28 +29,28 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex vec3(0, 0, 0), aabb(16, 16, MARGIN_ADJ), cull(UP | NORTH | SOUTH), - slope(Direction.UP, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b)) + updateUV(slope(Direction.UP, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b))) ); assemblePiece(context, transform, vec3(0, 0, MARGIN_ADJ), aabb(16, 16, 16 - MARGIN - MARGIN_ADJ).move(0, 0, MARGIN_ADJ), cull(UP | NORTH | SOUTH), - slope(Direction.UP, (a, b) -> map(MARGIN_ADJ, 16 - MARGIN, MARGIN, 16 - MARGIN_ADJ, b)) + updateUV(slope(Direction.UP, (a, b) -> map(MARGIN_ADJ, 16 - MARGIN, MARGIN, 16 - MARGIN_ADJ, b))) ); assemblePiece(context, transform, vec3(0, 0, 16 - MARGIN), aabb(16, 16, MARGIN).move(0, 0, 16 - MARGIN), cull(UP | NORTH), - slope(Direction.UP, (a, b) -> map(16 - MARGIN, 16, 16 - MARGIN_ADJ, 16, b)) + updateUV(slope(Direction.UP, (a, b) -> map(16 - MARGIN, 16, 16 - MARGIN_ADJ, 16, b))) ); assemblePiece(context, transform, vec3(0, 0, 0), aabb(16, 16, MARGIN_ADJ), cull(DOWN | NORTH | SOUTH), - slope(Direction.DOWN, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b)), + updateUV(slope(Direction.DOWN, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b))), translate(0, -16, 0), rotate( pivot(0, 0, 0), @@ -92,7 +92,7 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex vec3(0, 0, 16 - MARGIN_ADJ), aabb(16, 16, MARGIN_ADJ).move(0, 0, 16 - MARGIN_ADJ), cull(DOWN | NORTH | SOUTH), - slope(Direction.DOWN, (a, b) -> map(16 - MARGIN_ADJ, 16, MARGIN, 0, b)), + updateUV(slope(Direction.DOWN, (a, b) -> map(16 - MARGIN_ADJ, 16, MARGIN, 0, b))), rotate( pivot(16, 16, 16), angle(-45, 0, 0) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java index 035d7f085..d43f3fd5c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -23,7 +23,7 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex vec3(0, 0, 0), aabb(16, 16, 16), cull(NORTH), - slope(Direction.UP, (a, b) -> b) + updateUV(slope(Direction.UP, (a, b) -> b)) ); } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java deleted file mode 100644 index eaf2ee56f..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/fabric/UVHelperImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.fabric; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.UVHelper; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU; -import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV; - -public class UVHelperImpl { - public static T mapWithUV(T data, TextureAtlasSprite sprite, UVHelper.QuadVertexMapper mapper) { - MutableQuadView quad = (MutableQuadView) data; - Vec3 xyz0 = BakedQuadHelper.getXYZ(quad, 0); - Vec3 xyz1 = BakedQuadHelper.getXYZ(quad, 1); - Vec3 xyz2 = BakedQuadHelper.getXYZ(quad, 2); - Vec3 xyz3 = BakedQuadHelper.getXYZ(quad, 3); - - Vec3 uAxis = xyz3.add(xyz2) - .scale(.5); - Vec3 vAxis = xyz1.add(xyz2) - .scale(.5); - Vec3 center = xyz3.add(xyz2) - .add(xyz0) - .add(xyz1) - .scale(.25); - - float u0 = quad.spriteU(0, 0); - float u3 = quad.spriteU(3, 0); - float v0 = quad.spriteV(0, 0); - float v1 = quad.spriteV(1, 0); - - float uScale = (float) Math - .round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0)); - float vScale = (float) Math - .round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0)); - - if (uScale == 0) { - float v3 = quad.spriteV(3, 0); - float u1 = quad.spriteU(1, 0); - uAxis = xyz1.add(xyz2) - .scale(.5); - vAxis = xyz3.add(xyz2) - .scale(.5); - uScale = (float) Math - .round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0)); - vScale = (float) Math - .round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0)); - - } - - uAxis = uAxis.subtract(center) - .normalize(); - vAxis = vAxis.subtract(center) - .normalize(); - - for (int vertex = 0; vertex < 4; vertex++) { - Vec3 xyz = BakedQuadHelper.getXYZ(quad, vertex); - Vec3 newXyz = mapper.map(xyz, vertex); - Vec3 diff = newXyz.subtract(xyz); - - if (diff.lengthSqr() > 0) { - float u = quad.spriteU(vertex, 0); - float v = quad.spriteV(vertex, 0); - float uDiff = (float) uAxis.dot(diff) * uScale; - float vDiff = (float) vAxis.dot(diff) * vScale; - quad.sprite(vertex, 0, - sprite.getU(getUnInterpolatedU(sprite, u) + uDiff), - sprite.getV(getUnInterpolatedV(sprite, v) + vDiff)); - } - - BakedQuadHelper.setXYZ(quad, vertex, newXyz); - } - - return data; - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java deleted file mode 100644 index 38f2a42df..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/forge/UVHelperImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.forge; - -import com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.UVHelper; -import com.simibubi.create.foundation.model.BakedQuadHelper; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.world.phys.Vec3; - -import java.util.Arrays; - -import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU; -import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV; - -public class UVHelperImpl { - public static T mapWithUV(T data, TextureAtlasSprite sprite, UVHelper.QuadVertexMapper mapper) { - int[] vertexData = (int[]) data; - vertexData = Arrays.copyOf(vertexData, vertexData.length); - - Vec3 xyz0 = BakedQuadHelper.getXYZ(vertexData, 0); - Vec3 xyz1 = BakedQuadHelper.getXYZ(vertexData, 1); - Vec3 xyz2 = BakedQuadHelper.getXYZ(vertexData, 2); - Vec3 xyz3 = BakedQuadHelper.getXYZ(vertexData, 3); - - Vec3 uAxis = xyz3.add(xyz2) - .scale(.5); - Vec3 vAxis = xyz1.add(xyz2) - .scale(.5); - Vec3 center = xyz3.add(xyz2) - .add(xyz0) - .add(xyz1) - .scale(.25); - - float u0 = BakedQuadHelper.getU(vertexData, 0); - float u3 = BakedQuadHelper.getU(vertexData, 3); - float v0 = BakedQuadHelper.getV(vertexData, 0); - float v1 = BakedQuadHelper.getV(vertexData, 1); - - float uScale = (float) Math - .round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0)); - float vScale = (float) Math - .round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0)); - - if (uScale == 0) { - float v3 = BakedQuadHelper.getV(vertexData, 3); - float u1 = BakedQuadHelper.getU(vertexData, 1); - uAxis = xyz1.add(xyz2) - .scale(.5); - vAxis = xyz3.add(xyz2) - .scale(.5); - uScale = (float) Math - .round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0)); - vScale = (float) Math - .round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0)); - - } - - uAxis = uAxis.subtract(center) - .normalize(); - vAxis = vAxis.subtract(center) - .normalize(); - - for (int vertex = 0; vertex < 4; vertex++) { - Vec3 xyz = BakedQuadHelper.getXYZ(vertexData, vertex); - Vec3 newXyz = mapper.map(xyz, vertex); - Vec3 diff = newXyz.subtract(xyz); - - if (diff.lengthSqr() > 0) { - float u = BakedQuadHelper.getU(vertexData, vertex); - float v = BakedQuadHelper.getV(vertexData, vertex); - float uDiff = (float) uAxis.dot(diff) * uScale; - float vDiff = (float) vAxis.dot(diff) * vScale; - BakedQuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff)); - BakedQuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff)); - } - - BakedQuadHelper.setXYZ(vertexData, vertex, newXyz); - } - - return (T) vertexData; - } -} From ba3a7bc269ded0414ab40ca87fc074c145c10a4b Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 18 Jun 2024 11:55:50 +0800 Subject: [PATCH 07/71] Add documentation --- .../base/model/assembly/Assembler.java | 75 ++++++++++++++++--- .../base/model/assembly/quad/QuadSlope.java | 12 +++ 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index 1c7ec2cd4..f8a89bff5 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -13,13 +13,13 @@ public class Assembler { /** - * Assemble the quads of a piece of copycat material. + * Copy a piece of cuboid from the source model and assemble it to the copycat. * - * @param context Source and destination quads. - * @param globalTransform The global transform to apply to the piece. + * @param context Source and destination of this operation. + * @param globalTransform The global transform to apply to the entire operation, changing the positions, AABBs and cull faces. * @param offset In voxel space, the final position of the assembled piece. * @param select In voxel space, the selection on the source model to copy from. - * @param cull Faces to skip rendering in the destination model. Changed automatically according to `rotation` and `flipY`. + * @param cull Faces to skip rendering in the destination model. */ @ExpectPlatform public static void assemblePiece( @@ -33,14 +33,14 @@ public static void assemblePiece( } /** - * Assemble the quads of a piece of copycat material. + * Copy a piece of cuboid from the source model, apply quad transforms, and assemble it to the copycat. * - * @param context Source and destination quads. - * @param globalTransform The global transform to apply to the piece. + * @param context Source and destination of this operation. + * @param globalTransform The global transform to apply to the entire operation, changing the positions, AABBs, cull faces and quad transforms. * @param offset In voxel space, the final position of the assembled piece. * @param select In voxel space, the selection on the source model to copy from. - * @param cull Faces to skip rendering in the destination model. Changed automatically according to `rotation` and `flipY`. - * @param transforms Additional transforms to apply to the quads. + * @param cull Faces to skip rendering in the destination model. + * @param transforms Quad transforms to apply to the copied quads. */ @ExpectPlatform public static void assemblePiece( @@ -98,59 +98,114 @@ public static void assembleQuad(Source src, Destination de * Copy a quad from source to destination while applying the specified transforms. */ @ExpectPlatform - public static void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, QuadTransform... transforms) { + public static void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, GlobalTransform globalTransform, QuadTransform... transforms) { } + /** + * Create a mutable quad from the given vertex data. + */ @ExpectPlatform public static MutableQuad getMutableQuad(T vertexData) { return null; } + /** + * Specify faces to be culled. You should import static constants from {@link MutableCullFace} and use bitwise OR to combine them. + * + * @param mask The faces to be culled. Specify multiple faces by bitwise OR. + */ public static MutableCullFace cull(int mask) { return new MutableCullFace(mask); } + /** + * Specify a position in voxel space, where each block is 16 units. + */ public static MutableVec3 vec3(double x, double y, double z) { return new MutableVec3(x / 16, y / 16, z / 16); } + /** + * Specify a position in voxel space, where each block is 16 units. This position is used as a pivot point. + */ public static MutableVec3.AsPivot pivot(double x, double y, double z) { return new MutableVec3.AsPivot(x / 16, y / 16, z / 16); } + /** + * Specify axis angles in degrees. Rotations are applied in the order of X, Y, Z. + */ public static MutableVec3.AsAngle angle(double x, double y, double z) { return new MutableVec3.AsAngle(x, y, z); } + /** + * Specify scaling factors in each axis. 1 is the original size. + */ public static MutableVec3.AsScale scale(double x, double y, double z) { return new MutableVec3.AsScale(x, y, z); } + /** + * Specify a volume in voxel space, where each block is 16 units. This volume is used as a selection box. + *

+ * By default, volumes start at (0, 0, 0) and extend to the specified size. Use {@link MutableAABB#move(double, double, double)} to move the volume. + */ public static MutableAABB aabb(double sizeX, double sizeY, double sizeZ) { return new MutableAABB(sizeX / 16, sizeY / 16, sizeZ / 16); } + /** + * Freely rotate the quad around the pivot point. Rotations are performed in the order of X, Y, Z. + *

+ * Rotations of any angle and of multiple axes are allowed. + */ public static QuadRotate rotate(MutableVec3.AsPivot pivot, MutableVec3.AsAngle rot) { return new QuadRotate(pivot, rot); } + /** + * Scale the quad around the pivot point. + */ public static QuadScale scale(MutableVec3.AsPivot pivot, MutableVec3.AsScale scale) { return new QuadScale(pivot, scale); } + /** + * Translate the quad by the specified amount. + */ public static QuadTranslate translate(double x, double y, double z) { return new QuadTranslate(x / 16, y / 16, z / 16); } + /** + * Map the height of the quad in the specified direction to the specified function. + *

+ * For example, if the mapping direction is UP and the function returns a scaling factor of 0.5, the height of the quad will be halved. + * If the mapping direction is DOWN and the function returns 0.5, the bottom of the quad will be raised to 50% of its original height. + *

+ * The mapping function can return values that vary with the position of the vertex to achieve slopes. + */ public static QuadSlope slope(Direction face, QuadSlope.QuadSlopeFunction func) { return new QuadSlope(face, (a, b) -> func.apply(a * 16, b * 16) / 16); } + /** + * Shear the quad in the specified direction. + * + * @param axis The axis to be sheared. The direction of this axis will be changed while the other two axes remain the same. + * @param direction The direction to "pull" the positive end of the axis towards. + * @param amount The amount of shear in voxel space. 16 units is the width of a block. + */ public static QuadShear shear(Direction.Axis axis, Direction direction, double amount) { return new QuadShear(axis, direction, amount / 16); } + /** + * Wrap quad transforms so that the textures remain visually in the same position while the vertices are being moved, + * as opposed to the default behavior where the textures are stretched or squished along with the vertices. + */ public static QuadUVUpdate updateUV(QuadTransform... transforms) { return new QuadUVUpdate(transforms); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java index 0c6b8575f..bca1bd673 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java @@ -68,6 +68,18 @@ public static double map(double fromStart, double fromEnd, double toStart, doubl @FunctionalInterface public interface QuadSlopeFunction { + /** + * Given the two coordinates of a vertex, return a scaling factor for the height in the remaining axis. + *

    + *
  • If the X axis is being mapped, the first parameter is the Y coordinate and the second parameter is the Z coordinate.
  • + *
  • If the Y axis is being mapped, the first parameter is the X coordinate and the second parameter is the Z coordinate.
  • + *
  • If the Z axis is being mapped, the first parameter is the X coordinate and the second parameter is the Y coordinate.
  • + *
+ * + * @param a The first coordinate + * @param b The second coordinate + * @return The scaling factor for the height in the remaining axis + */ double apply(double a, double b); } } From 9d355440561ec64f09f0314ceda1f2550e8e75e9 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 18 Jun 2024 14:28:28 +0800 Subject: [PATCH 08/71] Add small epsilon to prevent texture UVs from messing up due to low precision from rubidium --- .../content/copycat/base/model/assembly/quad/QuadSlope.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java index bca1bd673..19b77c31f 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadSlope.java @@ -7,6 +7,8 @@ public record QuadSlope(Direction face, QuadSlopeFunction func) implements QuadTransform { + private static final double EPSILON = 0.02 / 16; + @Override public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { for (int i = 0; i < 4; i++) { @@ -33,6 +35,10 @@ public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { } double output = this.func.apply(a, b); + // prevent texture UVs from messing up due to loss of precision + if (Math.abs(output) < EPSILON) { + output = EPSILON; + } switch (this.face.getAxis()) { case X: From 3a503292a32ac549ae57a30b0e210f095e80f93a Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 18 Jun 2024 15:12:38 +0800 Subject: [PATCH 09/71] Generate slope shapes with loops, improve CT, add item model --- .../com/copycatsplus/copycats/CCShapes.java | 50 ++++------- .../copycat/slope/CopycatSlopeBlock.java | 84 ++++-------------- .../models/block/copycat_base/slope.json | 57 +++++++----- .../copycats/textures/block/copycat_slope.png | Bin 0 -> 7327 bytes 4 files changed, 69 insertions(+), 122 deletions(-) create mode 100644 common/src/main/resources/assets/copycats/textures/block/copycat_slope.png diff --git a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java index afb3f431e..8e4a47f1a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java @@ -137,42 +137,22 @@ public class CCShapes { .add(0, 0, 8, 8, 8, 16) .add(8, 0, 8, 16, 16, 16) .forDirectional(Direction.NORTH); - public static final VoxelShaper SLOPE = shape(Shapes.empty()).build((voxelShape, direction) -> { + private static final int SLOPE_SUBDIVISIONS = 16; + public static final VoxelShaper SLOPE_BOTTOM = shape(Shapes.empty()).build((voxelShape, direction) -> { VoxelShape shape = Shapes.empty(); - shape = Shapes.join(shape, Shapes.box(0, 0, 0, 1, 0.03125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.0625, 0, 0.9375, 0.09375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.125, 0, 0.875, 0.15625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.1875, 0, 0.8125, 0.21875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.25, 0, 0.75, 0.28125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.3125, 0, 0.6875, 0.34375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.375, 0, 0.625, 0.40625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.4375, 0, 0.5625, 0.46875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.8125, 0, 0.1875, 0.84375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.5, 0, 0.5, 0.53125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.5625, 0, 0.4375, 0.59375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.625, 0, 0.375, 0.65625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.6875, 0, 0.3125, 0.71875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.75, 0, 0.25, 0.78125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.9375, 0, 0.0625, 0.96875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.875, 0, 0.125, 0.90625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.65625, 0, 0.34375, 0.6875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.03125, 0, 0.96875, 0.0625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.09375, 0, 0.90625, 0.125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.15625, 0, 0.84375, 0.1875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.21875, 0, 0.78125, 0.25, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.28125, 0, 0.71875, 0.3125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.34375, 0, 0.65625, 0.375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.40625, 0, 0.59375, 0.4375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.46875, 0, 0.53125, 0.5, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.84375, 0, 0.15625, 0.875, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.53125, 0, 0.46875, 0.5625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.59375, 0, 0.40625, 0.625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.71875, 0, 0.28125, 0.75, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.78125, 0, 0.21875, 0.8125, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.96875, 0, 0.03125, 1, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.90625, 0, 0.09375, 0.9375, 1), BooleanOp.OR); - - return shape(shape).forDirectional(Direction.WEST); + for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 0, 0, 1, 1 - 1d / SLOPE_SUBDIVISIONS * i, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + } + shape = shape.optimize(); + return shape(shape).forDirectional(Direction.NORTH); + }, Direction.SOUTH); + public static final VoxelShaper SLOPE_TOP = shape(Shapes.empty()).build((voxelShape, direction) -> { + VoxelShape shape = Shapes.empty(); + for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 1d / SLOPE_SUBDIVISIONS * i, 0, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + } + shape = shape.optimize(); + return shape(shape).forDirectional(Direction.NORTH); }, Direction.SOUTH); private static Builder shape(VoxelShape shape) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java index 9ba46a005..1650c5089 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -49,8 +49,6 @@ public class CopycatSlopeBlock extends CTWaterloggedCopycatBlock implements ISta public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final EnumProperty HALF = BlockStateProperties.HALF; - private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); - public CopycatSlopeBlock(Properties pProperties) { super(pProperties); registerDefaultState(defaultBlockState() @@ -59,23 +57,6 @@ public CopycatSlopeBlock(Properties pProperties) { ); } - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, - BlockHitResult ray) { - - if (!player.isShiftKeyDown() && player.mayBuild()) { - ItemStack heldItem = player.getItemInHand(hand); - IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); - if (placementHelper.matchesItem(heldItem)) { - placementHelper.getOffset(player, world, state, pos, ray) - .placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); - return InteractionResult.SUCCESS; - } - } - - return super.use(state, world, pos, player, hand, ray); - } - @Override public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { @@ -84,11 +65,20 @@ public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState s BlockState toState = reader.getBlockState(toPos); if (toState.is(this)) { - // connecting to another copycat beam - return toState.getValue(FACING) != direction || toState.getValue(HALF) != half; + if (toState.getValue(FACING) == direction && toState.getValue(HALF)== half) return false; + + BlockPos diff = toPos.subtract(fromPos); + if (diff.equals(Vec3i.ZERO)) { + return false; + } + Direction connectFace = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (connectFace == null) { + return true; + } + + return !(direction == connectFace && connectFace == toState.getValue(FACING).getOpposite()); } else { - // doesn't connect to any other blocks - return true; + return false; } } @@ -111,8 +101,10 @@ public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos from if (toState.is(this)) { try { - return toState.getValue(FACING) == facing && toState.getValue(HALF) == half && - face.getAxis().isHorizontal() && face.getAxis() != facing.getAxis(); + return toState.getValue(FACING) == facing && + toState.getValue(HALF) == half && + face.getAxis().isHorizontal() && face.getAxis() != facing.getAxis() || + face == facing && face == toState.getValue(FACING).getOpposite(); } catch (IllegalStateException ignored) { return false; } @@ -165,7 +157,7 @@ protected void createBlockStateDefinition(StateDefinition.Builder { - - private PlacementHelper() { - super(CCBlocks.COPYCAT_HALF_PANEL::has, state -> state.getValue(FACING).getClockWise().getAxis(), FACING); - } - - @Override - public Predicate getItemPredicate() { - return i -> i.getItem() instanceof BlockItem - && (((BlockItem) i.getItem()).getBlock() instanceof CopycatSlopeBlock); - } - - @Override - public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos, BlockHitResult ray) { - List directions = IPlacementHelper.orderedByDistance(pos, ray.getLocation(), dir -> dir.getAxis() == axisFunction.apply(state)); - for (Direction dir : directions) { - int range = AllConfigs.server().equipment.placementAssistRange.get(); - if (player != null) { - //TODO: Add way to get reach attribute from platform - AttributeInstance reach = null; - if (reach != null && reach.hasModifier(ExtendoGripItem.singleRangeAttributeModifier)) - range += 4; - } - int poles = attachedPoles(world, pos, dir); - if (poles >= range) - continue; - - BlockPos newPos = pos.relative(dir, poles + 1); - BlockState newState = world.getBlockState(newPos); - - if (newState.canBeReplaced()) - return PlacementOffset.success(newPos, bState -> bState.setValue(property, state.getValue(property)).setValue(HALF, state.getValue(HALF))); - - } - - return PlacementOffset.fail(); - } - } } diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json index 6b928d8f3..515e1cde7 100644 --- a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope.json @@ -1,23 +1,38 @@ { - "credit": "Made with Blockbench", - "parent": "block/block", - "textures": { - "1": "create:block/copycat_base", - "2": "create:block/copycat_base", - "particle": "create:block/copycat_base" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": {"uv": [0, 0, 16, 16], "texture": "#2"}, - "east": {"uv": [0, 0, 16, 16], "texture": "#2"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#2"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#2"}, - "down": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "up": {"uv": [0, 0, 16, 16], "texture": "#1"} - } - } - ] + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "copycats:block/copycat_slope", + "2": "create:block/copycat_base", + "particle": "create:block/copycat_base" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "south": {"uv": [16, 0, 0, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#2"} + } + }, + { + "from": [4.6863, 0, 0], + "to": [16, 0, 16], + "rotation": {"angle": -45, "axis": "z", "origin": [16, 0, 0]}, + "faces": { + "up": {"uv": [0, 5, 16, 16], "rotation": 270, "texture": "#2"} + } + }, + { + "from": [-3.3137, 8, 0], + "to": [8, 8, 16], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "up": {"uv": [0, 0, 16, 11], "rotation": 270, "texture": "#2"} + } + } + ] } \ No newline at end of file diff --git a/common/src/main/resources/assets/copycats/textures/block/copycat_slope.png b/common/src/main/resources/assets/copycats/textures/block/copycat_slope.png new file mode 100644 index 0000000000000000000000000000000000000000..d556b4c60ad1512e5ca662007efa7c821b992559 GIT binary patch literal 7327 zcmeHLc~n!^*1us?kQpphgcz`jHY6bl34t&erc@aO9$-ZzBo~N~fh0gc1ROvtwcyB5 zoRGl*s-WNm8V1D?^r1y~K%fXJ1(AZHg5)~^oYwdLc&=6Yms#tqbI;j(|MuR$z3;jA zW~Y~jtA^SFH3)(<=x$El5TpPu6`(naV5%!Jy8%JU?0DY*kvAh2$rtcK*^w|(6vu~= zu$UbRLE^STfA;S^%jQiqnfJ|c3(;v{Z02#X4To!k8(NFTf34J`Ik@Hjp!>@+*#z~@ zh6~x%#70*QbEWj#OR~tvj>W8hBi<9;Fj6JXu-o-(#8#YHIP4xCfIiq$oZsQ?(j?Vq zcj)!Tp)PWQHt3_z`W3mJl~(4TGnjjNZkyU)Z3i^yJ)6}FPgfpX`0yohqLt_6m1e-XhefZ78cU6+ zHw?0~iylfUpo0ipLHLt{{1y3^Q2M#0m0iE>OLJ^Ny6&>n=yzRrqSm>ggYUHCV!6?_ z<-7I#*G_a7)vVb=Sd$s3)pqbjull0Uy`_C;iq5pp$zSc|67W~ge6!BEL=u^P)%Xr_>F5_EDLSf{m^X-1rTt z({6SXdD}YU^-d2RT5Ec2=XlpK|HBEIx`8hiZ#N8Gb7xIH{(gft^Felq->W@P{NX_m}HDS~rHQkj^R>|IcIZ3jB^ZV=IjcV7^i9cT# zpFFbGW8(3=?PXC)*Lw;e#NEC4Q;&^2`@Rda!j;$J^G5fcb=ix{d}U4XgWaL_Iqhe8WQV)usqP*Z2UYa`Ab) z5{nqVnqA4CF7xic%S=Zg;`+ZN9me(Im5}yy0q;5Ea-{9zcEnrzx z^(o!+i%|7_SYXHm9yF0Exd4F-L z=}66T-Ac}-h(!F>0jV*e`t(~Pb!pH2+_U(`i$&B`J$j}O207*v#hdz`OM9Ql_{|BU zBedN1QvuRREBEpp={bQd2@?)!#c$o01{ss=u5}uuEIE?uO)su9-G?sWsi__ows!PO z3;%7KM+-mrZ6=1M6c8KUrO{uKT>y5H^ zz*S{)D+W`ACbpA(FK8`?NIu9u^v^w$dYSb2wkO|qJ9n9u^`Vca+houj2bjjJcql;y)~VSu?qCFzTmA z5#woD$~kpcsS|Zln+_Qc%ajMBL85J9(?qi!H?0{xMvyn3Kr9& zqVxmRH7CFKTNIcV9nCjTsxi?HQ(fx(jrs7Ef_tdzs##-Eoi;nhpDS*U&p8p=Kt8hZ z!0w+K>La<%^Q!XI-}&nN>~`mY-m{c>wk<8xgoLZcD@p_s`oe{)t?2 zd_k}J+AM>{b$Jg3`-$U^G4uK=dI>EjQgs?ox^64C|GeDFD>Y@=-~#jSyhX+%FSM*D z%`UP8oaEh1V}s+FM)t2wCJvRZ&CcWR-HJOha;?(dWsAh(-tpE~V`UtY2PDJu3o9n} zQ?MiS_|n3ZjN~hvu0Jjn-rOYV)x^FoSe5$NEpho#FQ~KW>8}Eb1by#pe`9IfFU_h* z+Swm3Av86&l%e3$aaETuZ|2H6*^NW0`TBxOrz3@C;OS_{22a5N_tg|8k7L1L@j_q= zF^3PHk`QETFXl6t5wHju0*A4=RMgPrt0*L!MMe1&-LdX`8XV4cixu;99i*^>X zV=Pg2YDilFE0p5xo*)c^v$nRzU@bA0mS~`X7RGT! z3^AH3G?hb4V>rP=rhv^Cv3Xpi9Fq~kixyE)C?H3^kB`H5cmDv-70$2#_`rx6d<@P4 zi{WrEpIQh-&M^RFCZPXnA@l_=6But;$cq**Vdof_D>D5Qg2nt`&yN;FPNl=4;FF?!q^=ClocTRGffdY^dniH#U__brSoYZ!2AR5XWH*`pHc=| z?(P&P9y3}V9^HwGlKZEycuY2nGIa@C5<|%ZoHd#d!XTgtFoA#$A%iPxCYgb?VgMO| z@Cg*1D-U&Gx0bQ+7cf^LKCn|GMd34!)O+PNVLXV5<+21t4|<2 z1#HljjL1);l0&fo6q7_GS&5$O)%7deNyUOAGAB9j{1+C=?igdw|Vl@nVG^MZRnf>?2~x`NWZM zWGibt4rfIokZ=UzMdPM5`vEd&~I@}8gRdLKAydNq9$M6#zuNaR%GQW(r>CqhOH%$jlp z?50J`a0WLF26y;OOTFJ`|Ce&%u~>X)2*DB^8iFIE33x0KZB4>jp)EsUE4(!WXU!sz zKSvkxLPfC*0qhtCG6mUy7MjWixon0^^Uw8T!(lm7SW5yL;Nr->I0A)0q~NSjn3-fT z@_YJywzio6$A|5d!Y79Su$$fkhYL8XFdq)98NTEc&f;&T4zuV1K!0`eMf`rH>nmMf z#K0FRf9idlyLHfu=diQZTN9(UJrPn8(082Ii(DDDAKe@pr|;8*YVVHu=tFH=0y@%Qv-XQ%AE)B(Ek=9PkWl1x!sHmRt+L52WBQCkXTDVXhL z2xQ`9{Kr(>(CWz8Cwv=k*KN&je`%@R-9q!io{bxo=e3@JJ+kU*I#Sf~Io4`R>$ z^2Ojcuk~M>OX3Y7yQ&1}7Nn9)NJbzvf+06WL+IbLzwBz+AZeD4>4)3jDVE7hRR6Ke zKXsJ&7Lj_|-tO?Er2aM{5~OVfxL*jE&;aF70cW%DLw*anKdzatnSU9kX`j; zak8f*(NF@a&;?q74=O Date: Wed, 19 Jun 2024 21:59:29 +0800 Subject: [PATCH 10/71] Update readme --- README.MD | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/README.MD b/README.MD index 21c44de95..fe8cb832f 100644 --- a/README.MD +++ b/README.MD @@ -1,5 +1,3 @@ -

Logo

-

Create: Copycats+

@@ -12,7 +10,9 @@ All the copycats you've ever wanted, combined into a single mod! -![Discord Banner](https://discordapp.com/api/guilds/1202240504809652365/widget.png?style=banner2) +[![Discord Banner](https://discordapp.com/api/guilds/1202240504809652365/widget.png?style=banner2)](https://discord.gg/YxPPFHn4SS) + +[![BisectHosting](https://copycats-site.vercel.app/api/banner)](https://copycats-site.vercel.app/api/link) ## Features @@ -22,40 +22,36 @@ All the copycats you've ever wanted, combined into a single mod! - Copycat Block - Copycat Slab - - Supports all orientations and double slab variants. + - Supports all orientations and double slab variants. - Copycat Beam - - A centered Copycat Step. + - A centered Copycat Step. - Copycat Vertical Step - Copycat Half Panel - - Supports 4 orientations on each block face + - Supports 4 orientations on each block face - Copycat Stairs - Copycat Fence - Copycat Fence Gate - Copycat Trapdoor - Copycat Wall - Copycat Board - - A 1-pixel thick panel. Multiple boards can be placed in the same block space like glow lichen. + - A 1-pixel thick panel. Multiple boards can be placed in the same block space like glow lichen. - Copycat Box - - A pre-assembled copycat board. + - A pre-assembled copycat board. - Copycat Catwalk - - A pre-assembled copycat board. + - A pre-assembled copycat board. - Copycat Byte - - A mini-block. Bytes can be placed/dismantled individually, 8 of which forms a full block. + - A mini-block. Bytes can be placed/dismantled individually, 8 of which forms a full block. - Copycat Layer - - Can be placed in any orientation and stacks to full block size. + - Can be placed in any orientation and stacks to full block size. - Copycat Half Layer - - Can be stacked to full block size with 2 columns of half layers in one block space. + - Can be stacked to full block size with 2 columns of half layers in one block space. - Copycat Slice - - Can be resized to 8 different sizes. + - Can be resized to 8 different sizes. - Copycat Vertical Slice - - Can be resized to 8 different sizes. + - Can be resized to 8 different sizes. - Copycat Wooden/Stone Button - Copycat Wooden/Stone Pressure Plate - Copycat Light/Heavy Weighted Pressure Plate -- Copycat Ladder - - A ladder block that can be made to look like any block and can be placed without needing a supporting block behind it. -- Copycat Ghost Block - - A full sized block with no collision, meaning it can be walked/fallen through. ## Download From ead93a4ed64665883e050b43b7205d2435732fe3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 20 Jun 2024 15:30:10 +0800 Subject: [PATCH 11/71] Add real block hit result to block effects Particles are now slightly more accurate, but they may still be off sometimes since particles are determined by the copycat model, which has no info on where the player is standing --- .../MultiStateCopycatBlockCombinerMixin.java | 11 +++++----- .../MultiStateCopycatBlockCombinerMixin.java | 22 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java index e4820b51a..773ba4728 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java @@ -12,10 +12,7 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.*; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SoundType; @@ -106,7 +103,8 @@ public float getExplosionResistance(BlockState state, BlockGetter level, BlockPo @Override public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos pos, BlockState state2, LivingEntity entity, int numberOfParticles) { if (state1.getBlock() instanceof MultiStateCopycatBlock mscb) { - String property = mscb.getProperty(state1, level, pos, new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, true), true); + BlockHitResult hitResult = level.clip(new ClipContext(entity.position(), entity.position().add(0, -2, 0), ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, entity)); + String property = mscb.getProperty(state1, level, pos, hitResult, true); AtomicReference mat = new AtomicReference<>(AllBlocks.COPYCAT_BASE.getDefaultState()); mscb.withBlockEntityDo(level, pos, mscbe -> mat.set(mscbe.getMaterialItemStorage().getMaterialItem(property).material())); return maybeMaterialAs(level, pos, CustomLandingEffectsBlock.class, @@ -119,7 +117,8 @@ public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos @Override public boolean addRunningEffects(BlockState state, Level level, BlockPos pos, Entity entity) { if (state.getBlock() instanceof MultiStateCopycatBlock mscb) { - String property = mscb.getProperty(state, level, pos, new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, true), true); + BlockHitResult hitResult = level.clip(new ClipContext(entity.position(), entity.position().add(0, -2, 0), ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, entity)); + String property = mscb.getProperty(state, level, pos, hitResult, true); AtomicReference mat = new AtomicReference<>(AllBlocks.COPYCAT_BASE.getDefaultState()); mscb.withBlockEntityDo(level, pos, mscbe -> mat.set(mscbe.getMaterialItemStorage().getMaterialItem(property).material())); return maybeMaterialAs(level, pos, CustomRunningEffectsBlock.class, diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java index eb5c2c4b6..958f6c404 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java @@ -8,10 +8,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.*; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SoundType; @@ -38,7 +35,9 @@ public MultiStateCopycatBlockCombinerMixin(Properties properties) { @Override public SoundType getSoundType(BlockState state, LevelReader level, BlockPos pos, Entity entity) { - return getMaterial(level, pos).getSoundType(); + // There really is no easy way to know which part of the block is being interacted with + // So returning sounds of the copycat base should be less confusing + return state.getSoundType(); } @Override @@ -86,10 +85,11 @@ public float getExplosionResistance(BlockState state, BlockGetter level, BlockPo @Override public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos pos, BlockState state2, LivingEntity entity, int numberOfParticles) { if (state1.getBlock() instanceof MultiStateCopycatBlock mscb) { - String property = mscb.getProperty(state1, level, pos, new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, true), true); + BlockHitResult hitResult = level.clip(new ClipContext(entity.position(), entity.position().add(0, -2, 0), ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, entity)); + String property = mscb.getProperty(state1, level, pos, hitResult, true); AtomicReference mat = new AtomicReference<>(AllBlocks.COPYCAT_BASE.getDefaultState()); mscb.withBlockEntityDo(level, pos, mscbe -> mat.set(mscbe.getMaterialItemStorage().getMaterialItem(property).material())); - return mat.get().getBlock().addLandingEffects(state1, level, pos, state2, entity, numberOfParticles); + return mat.get().addLandingEffects(level, pos, mat.get(), entity, numberOfParticles); } return false; } @@ -97,10 +97,11 @@ public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos @Override public boolean addRunningEffects(BlockState state, Level level, BlockPos pos, Entity entity) { if (state.getBlock() instanceof MultiStateCopycatBlock mscb) { - String property = mscb.getProperty(state, level, pos, new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, true), true); + BlockHitResult hitResult = level.clip(new ClipContext(entity.position(), entity.position().add(0, -2, 0), ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, entity)); + String property = mscb.getProperty(state, level, pos, hitResult, true); AtomicReference mat = new AtomicReference<>(AllBlocks.COPYCAT_BASE.getDefaultState()); mscb.withBlockEntityDo(level, pos, mscbe -> mat.set(mscbe.getMaterialItemStorage().getMaterialItem(property).material())); - return mat.get().getBlock().addRunningEffects(state, level, pos, entity); + return mat.get().addRunningEffects(level, pos, entity); } return false; } @@ -118,7 +119,8 @@ public float getEnchantPowerBonus(BlockState state, LevelReader level, BlockPos @Override public void fallOn(@NotNull Level pLevel, @NotNull BlockState state, @NotNull BlockPos pPos, @NotNull Entity pEntity, float p_152430_) { if (state.getBlock() instanceof MultiStateCopycatBlock mscb) { - String property = mscb.getProperty(state, pLevel, pPos, new BlockHitResult(Vec3.atCenterOf(pPos), Direction.UP, pPos, true), true); + BlockHitResult hitResult = pLevel.clip(new ClipContext(pEntity.position(), pEntity.position().add(0, -2, 0), ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, pEntity)); + String property = mscb.getProperty(state, pLevel, pPos, hitResult, true); AtomicReference material = new AtomicReference<>(AllBlocks.COPYCAT_BASE.getDefaultState()); mscb.withBlockEntityDo(pLevel, pPos, mscbe -> material.set(mscbe.getMaterialItemStorage().getMaterialItem(property).material())); material.get().getBlock().fallOn(pLevel, material.get(), pPos, pEntity, p_152430_); From 77485559c6d974d36f8fc1a0534ce8b3b2de94d3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 20 Jun 2024 15:37:20 +0800 Subject: [PATCH 12/71] Check if the player is holding shift, instead of crouching, fixes #61 --- .../copycats/content/copycat/base/ICTCopycatBlock.java | 2 +- .../copycat/base/multistate/ICTMultiStateCopycatBlock.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java index e34151e95..1632df310 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java @@ -29,7 +29,7 @@ default boolean allowCTAppearance(BlockState state, BlockAndTintGetter level, Bl } default InteractionResult toggleCT(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) { - if (pPlayer.isCrouching() && pPlayer.getItemInHand(pHand).equals(ItemStack.EMPTY)) { + if (pPlayer.isShiftKeyDown() && pPlayer.getItemInHand(pHand).equals(ItemStack.EMPTY)) { CopycatBlockEntity be = getBlockEntity(pLevel, pPos); if (be instanceof CTCopycatBlockEntity ctbe) { ctbe.setCTEnabled(!ctbe.isCTEnabled()); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java index 29bf1fba7..c9f5b5e96 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java @@ -27,7 +27,7 @@ default boolean allowCTAppearance(BlockState state, BlockAndTintGetter level, Bl } default InteractionResult toggleCT(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) { - if (pPlayer.isCrouching() && pPlayer.getItemInHand(pHand).equals(ItemStack.EMPTY)) { + if (pPlayer.isShiftKeyDown() && pPlayer.getItemInHand(pHand).equals(ItemStack.EMPTY)) { MultiStateCopycatBlockEntity be = getBlockEntity(pLevel, pPos); if (be instanceof CTCopycatBlockEntity ctbe) { ctbe.setCTEnabled(!ctbe.isCTEnabled()); From 8d056c9dffb4da0f93d81f6c8fc8e3cdcdab6445 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 20 Jun 2024 21:02:55 +0800 Subject: [PATCH 13/71] Fix half panel rotation --- .../half_panel/CopycatHalfPanelBlock.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_panel/CopycatHalfPanelBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_panel/CopycatHalfPanelBlock.java index 189f91fb3..c814092fe 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_panel/CopycatHalfPanelBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_panel/CopycatHalfPanelBlock.java @@ -230,7 +230,34 @@ public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState sta @SuppressWarnings("deprecation") @Override public @NotNull BlockState rotate(@NotNull BlockState pState, Rotation pRot) { - return pState.setValue(FACING, pRot.rotate(pState.getValue(FACING))); + Direction facing = pState.getValue(FACING); + Direction offset = pState.getValue(OFFSET); + Vec3i offsetNormal = getOffsetFacing(facing, offset).getNormal(); + switch (pRot) { + case CLOCKWISE_90: + offsetNormal = new Vec3i(-offsetNormal.getZ(), offsetNormal.getY(), offsetNormal.getX()); + break; + case CLOCKWISE_180: + offsetNormal = new Vec3i(-offsetNormal.getX(), offsetNormal.getY(), -offsetNormal.getZ()); + break; + case COUNTERCLOCKWISE_90: + offsetNormal = new Vec3i(offsetNormal.getZ(), offsetNormal.getY(), -offsetNormal.getX()); + break; + default: + break; + } + Direction newFacing = pRot.rotate(facing); + Vec3i facingNormal = newFacing.getNormal(); + if (offsetNormal.getY() != 0) { + if (offsetNormal.getX() == 0 && facingNormal.getX() != 0) { + offsetNormal = new Vec3i(offsetNormal.getY(), offsetNormal.getX(), offsetNormal.getZ()); + } else { + offsetNormal = new Vec3i(offsetNormal.getX(), offsetNormal.getZ(), offsetNormal.getY()); + } + } + return pState + .setValue(FACING, newFacing) + .setValue(OFFSET, Objects.requireNonNull(Direction.fromDelta(offsetNormal.getX(), offsetNormal.getY(), offsetNormal.getZ()))); } @SuppressWarnings("deprecation") From c0734c9e72c89d9373a2e6fb7913ffb977f816ce Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Fri, 21 Jun 2024 10:02:26 +0800 Subject: [PATCH 14/71] Mark ModelBlockRenderer mixin as optional because rubidium may overwrite it --- .../copycat/base/multistate/ModelBlockRendererMixin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/ModelBlockRendererMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/ModelBlockRendererMixin.java index a19c0cb34..106c5543c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/ModelBlockRendererMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/ModelBlockRendererMixin.java @@ -21,7 +21,8 @@ public class ModelBlockRendererMixin { at = @At( value = "INVOKE", target = "Lnet/minecraft/client/color/block/BlockColors;getColor(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;I)I" - ) + ), + require = 0 ) private void beforeColor(BlockAndTintGetter level, BlockState state, BlockPos pos, VertexConsumer consumer, PoseStack.Pose pose, BakedQuad quad, float brightness0, float brightness1, float brightness2, float brightness3, int lightmap0, int lightmap1, int lightmap2, int lightmap3, int packedOverlay, CallbackInfo ci) { if (quad.getSprite() instanceof MultiStateTextureAtlasSprite sprite) @@ -34,7 +35,8 @@ private void beforeColor(BlockAndTintGetter level, BlockState state, BlockPos po value = "INVOKE", target = "Lnet/minecraft/client/color/block/BlockColors;getColor(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;I)I", shift = At.Shift.AFTER - ) + ), + require = 0 ) private void afterColor(BlockAndTintGetter level, BlockState state, BlockPos pos, VertexConsumer consumer, PoseStack.Pose pose, BakedQuad quad, float brightness0, float brightness1, float brightness2, float brightness3, int lightmap0, int lightmap1, int lightmap2, int lightmap3, int packedOverlay, CallbackInfo ci) { MultiStateRenderManager.setRenderingProperty(null); From 71ed12430809987fda4cb44d4d964dbac4b38747 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 11:19:03 +0800 Subject: [PATCH 15/71] Implement multi-state block rotation and mirroring --- .../copycats/CCBlockStateProperties.java | 2 + .../base/multistate/BlockStateTransform.java | 115 ++++++++++++++++++ .../base/multistate/MaterialItemStorage.java | 7 ++ .../multistate/MultiStateCopycatBlock.java | 56 +++++++++ .../MultiStateCopycatBlockEntity.java | 20 +++ .../WaterloggedMultiStateCopycatBlock.java | 10 +- .../copycat/board/CopycatBoardBlock.java | 32 ++++- .../copycat/bytes/CopycatByteBlock.java | 46 +++++-- .../half_layer/CopycatHalfLayerBlock.java | 25 +++- .../copycat/slab/CopycatSlabBlock.java | 28 ++++- .../copycat/test_block/CopycatTestBlock.java | 39 ++++++ 11 files changed, 357 insertions(+), 23 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/BlockStateTransform.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockStateProperties.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockStateProperties.java index 8506141ed..4b2fa1118 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockStateProperties.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockStateProperties.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats; +import com.copycatsplus.copycats.content.copycat.base.multistate.BlockStateTransform; import net.minecraft.util.StringRepresentable; import net.minecraft.world.level.block.state.properties.EnumProperty; import org.jetbrains.annotations.NotNull; @@ -8,6 +9,7 @@ public class CCBlockStateProperties { public static final EnumProperty VERTICAL_STAIR_SHAPE = EnumProperty.create("vertical_stair_shape", VerticalStairShape.class); public static final EnumProperty SIDE = EnumProperty.create("side", Side.class); + public static final EnumProperty TRANSFORM = EnumProperty.create("transform", BlockStateTransform.class); public enum Side implements StringRepresentable { LEFT, diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/BlockStateTransform.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/BlockStateTransform.java new file mode 100644 index 000000000..5c27bb3db --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/BlockStateTransform.java @@ -0,0 +1,115 @@ +package com.copycatsplus.copycats.content.copycat.base.multistate; + +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +/** + * Represents the symmetry group of a block state (aka a square). + *

+ * Ref: Group (mathematics) - Wikipedia + *

+ * Using an imaginary quad that is facing up, the vertex at -X and -Z is A, +X and -Z is B, +X and +Z is C, and -X and +Z is D. + * The order of the vertices represents a transformed state of the block. + */ +public enum BlockStateTransform implements StringRepresentable { + ABCD, + BCDA, + CDAB, + DABC, + ADCB, + DCBA, + CBAD, + BADC; + + public BlockStateTransform getClockwise() { + return switch (this) { + case ABCD -> BCDA; + case BCDA -> CDAB; + case CDAB -> DABC; + case DABC -> ABCD; + case ADCB -> DCBA; + case DCBA -> CBAD; + case CBAD -> BADC; + case BADC -> ADCB; + }; + } + + public BlockStateTransform getCounterClockwise() { + return switch (this) { + case ABCD -> DABC; + case BCDA -> ABCD; + case CDAB -> BCDA; + case DABC -> CDAB; + case ADCB -> BADC; + case DCBA -> ADCB; + case CBAD -> DCBA; + case BADC -> CBAD; + }; + } + + public BlockStateTransform flipX() { + return switch (this) { + case ABCD -> BADC; + case BCDA -> CBAD; + case CDAB -> DCBA; + case DABC -> ADCB; + case ADCB -> DABC; + case DCBA -> CDAB; + case CBAD -> BCDA; + case BADC -> ABCD; + }; + } + + public BlockStateTransform flipZ() { + return switch (this) { + case ABCD -> DCBA; + case BCDA -> ADCB; + case CDAB -> BADC; + case DABC -> CBAD; + case ADCB -> BCDA; + case DCBA -> ABCD; + case CBAD -> DABC; + case BADC -> CDAB; + }; + } + + @Override + public @NotNull String getSerializedName() { + return name().toLowerCase(); + } + + public void undoTransform(Consumer rotate, Consumer mirror) { + switch (this) { + case ABCD -> { + } + case BCDA -> { + rotate.accept(Rotation.CLOCKWISE_90); + } + case CDAB -> { + rotate.accept(Rotation.CLOCKWISE_180); + } + case DABC -> { + rotate.accept(Rotation.COUNTERCLOCKWISE_90); + } + case ADCB -> { + mirror.accept(Mirror.FRONT_BACK); + rotate.accept(Rotation.CLOCKWISE_90); + } + case DCBA -> { + mirror.accept(Mirror.FRONT_BACK); + } + case CBAD -> { + mirror.accept(Mirror.FRONT_BACK); + rotate.accept(Rotation.COUNTERCLOCKWISE_90); + } + case BADC -> { + mirror.accept(Mirror.FRONT_BACK); + rotate.accept(Rotation.CLOCKWISE_180); + } + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java index 97cd10520..a6cedf7d0 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java @@ -15,6 +15,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.stream.Collectors; public class MaterialItemStorage { @@ -62,6 +63,12 @@ public boolean hasCustomMaterial(String property) { return !storage.get(property).material().is(AllBlocks.COPYCAT_BASE.get()); } + public void remapStorage(Function keyMapper) { + Map newStorage = new HashMap<>(); + storage.forEach((key, materialItem) -> newStorage.put(keyMapper.apply(key), materialItem)); + storage = newStorage; + } + public CompoundTag serialize() { CompoundTag root = new CompoundTag(); storage.forEach((key, materialItem) -> root.put(key, materialItem.serialize())); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java index 4559d5d30..b7c1f15c7 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.base.multistate; import com.copycatsplus.copycats.CCBlockEntityTypes; +import com.copycatsplus.copycats.CCBlockStateProperties; import com.copycatsplus.copycats.content.copycat.base.IStateType; import com.copycatsplus.copycats.content.copycat.base.StateType; import com.simibubi.create.AllBlocks; @@ -21,6 +22,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; @@ -37,13 +39,16 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraft.world.ticks.TickPriority; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -57,8 +62,18 @@ public abstract class MultiStateCopycatBlock extends Block implements IBE, IWrenchable, ISpecialBlockItemRequirement, IStateType { + public static final EnumProperty TRANSFORM = CCBlockStateProperties.TRANSFORM; + public MultiStateCopycatBlock(Properties properties) { super(properties); + registerDefaultState(defaultBlockState() + .setValue(TRANSFORM, BlockStateTransform.ABCD) + ); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + super.createBlockStateDefinition(builder.add(TRANSFORM)); } public abstract int maxMaterials(); @@ -413,6 +428,47 @@ public static VoxelShape multiPlatformGetShape(@NotNull BlockState pState, @NotN return null; } + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState updateShape(@NotNull BlockState state, @NotNull Direction direction, @NotNull BlockState neighborState, LevelAccessor level, @NotNull BlockPos pos, @NotNull BlockPos neighborPos) { + level.scheduleTick(pos, this, 0, TickPriority.EXTREMELY_HIGH); + return super.updateShape(state, direction, neighborState, level, pos, neighborPos); + } + + @SuppressWarnings("deprecation") + @Override + public void tick(@NotNull BlockState state, @NotNull ServerLevel level, @NotNull BlockPos pos, @NotNull RandomSource random) { + withBlockEntityDo(level, pos, MultiStateCopycatBlockEntity::updateTransform); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState rotate(@NotNull BlockState state, Rotation rotation) { + return switch (rotation) { + case CLOCKWISE_180 -> + super.rotate(state, rotation).setValue(TRANSFORM, state.getValue(TRANSFORM).getClockwise().getClockwise()); + case COUNTERCLOCKWISE_90 -> + super.rotate(state, rotation).setValue(TRANSFORM, state.getValue(TRANSFORM).getCounterClockwise()); + case CLOCKWISE_90 -> + super.rotate(state, rotation).setValue(TRANSFORM, state.getValue(TRANSFORM).getClockwise()); + default -> super.rotate(state, rotation); + }; + } + + public abstract void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation); + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState mirror(@NotNull BlockState state, Mirror mirror) { + return switch (mirror) { + case FRONT_BACK -> super.mirror(state, mirror).setValue(TRANSFORM, state.getValue(TRANSFORM).flipZ()); + case LEFT_RIGHT -> super.mirror(state, mirror).setValue(TRANSFORM, state.getValue(TRANSFORM).flipX()); + default -> super.mirror(state, mirror); + }; + } + + public abstract void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror); + @Environment(EnvType.CLIENT) public static BlockColor wrappedColor() { return new WrappedBlockColor(); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java index e1834986c..1ebea5156 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java @@ -18,6 +18,9 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.TrapDoorBlock; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -41,6 +44,23 @@ public MultiStateCopycatBlockEntity(BlockEntityType type, BlockPos pos, Block } } + @Override + public void setLevel(@NotNull Level level) { + super.setLevel(level); + } + + public void updateTransform() { + BlockStateTransform transform = getBlockState().getValue(MultiStateCopycatBlock.TRANSFORM); + if (transform != BlockStateTransform.ABCD) { + MultiStateCopycatBlock block = (MultiStateCopycatBlock) getBlockState().getBlock(); + transform.undoTransform( + r -> block.rotate(getBlockState(), this, r), + m -> block.mirror(getBlockState(), this, m) + ); + } + getLevel().setBlock(getBlockPos(), getBlockState().setValue(MultiStateCopycatBlock.TRANSFORM, BlockStateTransform.ABCD), 2 | 4 | 16 | 32); + } + public boolean cycleMaterial(String property) { BlockState material = getMaterialItemStorage().getMaterialItem(property).material(); if (material.hasProperty(TrapDoorBlock.HALF) && material.getOptionalValue(TrapDoorBlock.OPEN) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/WaterloggedMultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/WaterloggedMultiStateCopycatBlock.java index 78ab66bd6..5981fe5e8 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/WaterloggedMultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/WaterloggedMultiStateCopycatBlock.java @@ -9,6 +9,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.material.FluidState; +import org.jetbrains.annotations.NotNull; public abstract class WaterloggedMultiStateCopycatBlock extends MultiStateCopycatBlock implements ProperWaterloggedBlock { public WaterloggedMultiStateCopycatBlock(Properties properties) { @@ -32,8 +33,13 @@ public BlockState getStateForPlacement(BlockPlaceContext pContext) { } @Override - public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState, - LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) { + public @NotNull BlockState updateShape(@NotNull BlockState pState, + @NotNull Direction pDirection, + @NotNull BlockState pNeighborState, + @NotNull LevelAccessor pLevel, + @NotNull BlockPos pCurrentPos, + @NotNull BlockPos pNeighborPos) { + super.updateShape(pState, pDirection, pNeighborState, pLevel, pCurrentPos, pNeighborPos); updateWater(pLevel, pState, pCurrentPos); return pState; } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java index f037c8bfa..cf219da17 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java @@ -3,6 +3,8 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MaterialItemStorage; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.google.common.collect.ImmutableMap; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Iterate; @@ -280,18 +282,44 @@ public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState sta return getMaterial(level, pos, property).skipRendering(neighborState, dir.getOpposite()); } - @SuppressWarnings("deprecation") @Override public @NotNull BlockState rotate(@NotNull BlockState pState, Rotation pRotation) { + pState = super.rotate(pState, pRotation); return mapDirections(pState, pRotation::rotate); } - @SuppressWarnings("deprecation") + @Override + public void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation) { + be.getMaterialItemStorage().remapStorage(key -> directionToProperty(rotation.rotate(propertyToDirection(key)))); + } + + private static Direction propertyToDirection(String property) { + return switch (property) { + case "up" -> Direction.UP; + case "down" -> Direction.DOWN; + case "north" -> Direction.NORTH; + case "south" -> Direction.SOUTH; + case "east" -> Direction.EAST; + case "west" -> Direction.WEST; + default -> throw new IllegalStateException("Unexpected value: " + property); + }; + } + + public static String directionToProperty(Direction direction) { + return direction.getName().toLowerCase(); + } + @Override public @NotNull BlockState mirror(@NotNull BlockState pState, Mirror pMirror) { + pState = super.mirror(pState, pMirror); return mapDirections(pState, pMirror::mirror); } + @Override + public void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror) { + be.getMaterialItemStorage().remapStorage(key -> directionToProperty(mirror.mirror(propertyToDirection(key)))); + } + private BlockState mapDirections(BlockState pState, Function pDirectionalFunction) { BlockState blockstate = pState; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java index 23b17f82f..45f0a9b6c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java @@ -2,6 +2,7 @@ import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.google.common.collect.ImmutableMap; import com.mojang.math.OctahedralGroup; import com.simibubi.create.AllBlocks; @@ -252,25 +253,26 @@ public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) return InteractionResult.SUCCESS; } - @SuppressWarnings("deprecation") @Override public @NotNull BlockState rotate(@NotNull BlockState pState, @NotNull Rotation pRotation) { - if (pRotation == Rotation.CLOCKWISE_90) { - return mapBytes(pState, bite -> bite(!bite.z, bite.y, bite.x)); - } else if (pRotation == Rotation.CLOCKWISE_180) { - return mapBytes(pState, bite -> bite(!bite.x, bite.y, !bite.z)); - } else if (pRotation == Rotation.COUNTERCLOCKWISE_90) { - return mapBytes(pState, bite -> bite(bite.z, bite.y, !bite.x)); - } - return pState; + pState = super.rotate(pState, pRotation); + return mapBytes(pState, bite -> bite.rotate(pRotation)); + } + + @Override + public void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation) { + be.getMaterialItemStorage().remapStorage(key -> byByte(byteMap.get(key).rotate(rotation)).getName()); } - @SuppressWarnings("deprecation") @Override public @NotNull BlockState mirror(@NotNull BlockState pState, Mirror pMirror) { - boolean invertX = pMirror.rotation() == OctahedralGroup.INVERT_X; - boolean invertZ = pMirror.rotation() == OctahedralGroup.INVERT_Z; - return mapBytes(pState, bite -> bite(invertX != bite.x, bite.y, invertZ != bite.z)); + pState = super.mirror(pState, pMirror); + return mapBytes(pState, bite -> bite.mirror(pMirror)); + } + + @Override + public void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror) { + be.getMaterialItemStorage().remapStorage(key -> byByte(byteMap.get(key).mirror(mirror)).getName()); } public static Vec3 clampToBlockPos(Vec3 vec, BlockPos pos) { @@ -371,6 +373,24 @@ public Byte relative(Direction direction) { return set(direction.getAxis(), !get(direction.getAxis())); } + public Byte rotate(Rotation rotation) { + if (rotation == Rotation.CLOCKWISE_90) { + return new Byte(!this.z, this.y, this.x); + } else if (rotation == Rotation.CLOCKWISE_180) { + return new Byte(!this.x, this.y, !this.z); + } else if (rotation == Rotation.COUNTERCLOCKWISE_90) { + return new Byte(this.z, this.y, !this.x); + } else { + return this; + } + } + + public Byte mirror(Mirror mirror) { + boolean invertX = mirror.rotation() == OctahedralGroup.INVERT_X; + boolean invertZ = mirror.rotation() == OctahedralGroup.INVERT_Z; + return new Byte(invertX != this.x, this.y, invertZ != this.z); + } + @Override public int hashCode() { return i(x) + i(y) << 1 + i(z) << 2; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java index a5eccac7c..ee584200e 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java @@ -3,6 +3,7 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.google.common.collect.ImmutableMap; import com.simibubi.create.AllBlocks; @@ -251,9 +252,9 @@ public boolean canConnectTexturesToward(String property, BlockAndTintGetter read return toState.is(this); } - @SuppressWarnings("deprecation") @Override public @NotNull BlockState rotate(@NotNull BlockState state, Rotation rot) { + state = super.rotate(state, rot); Function swap = axis -> axis == Axis.Z ? Axis.X : Axis.Z; return switch (rot) { case NONE -> state; @@ -284,11 +285,29 @@ public boolean canConnectTexturesToward(String property, BlockAndTintGetter read } @Override - @SuppressWarnings("deprecation") - public @NotNull BlockState mirror(BlockState state, Mirror mirrorIn) { + public void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation) { + Axis axis = state.getValue(AXIS); + if (rotation == Rotation.CLOCKWISE_90 && axis == Axis.X || + rotation == Rotation.CLOCKWISE_180 || + rotation == Rotation.COUNTERCLOCKWISE_90 && axis == Axis.Z) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(POSITIVE_LAYERS.getName()) ? NEGATIVE_LAYERS.getName() : POSITIVE_LAYERS.getName()); + } + } + + @Override + public @NotNull BlockState mirror(@NotNull BlockState state, Mirror mirrorIn) { + state = super.mirror(state, mirrorIn); return state.rotate(mirrorIn.getRotation(Direction.get(AxisDirection.POSITIVE, state.getValue(AXIS)))); } + @Override + public void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror) { + Axis axis = state.getValue(AXIS); + if (mirror == Mirror.FRONT_BACK && axis == Axis.Z || mirror == Mirror.LEFT_RIGHT && axis == Axis.X) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(POSITIVE_LAYERS.getName()) ? NEGATIVE_LAYERS.getName() : POSITIVE_LAYERS.getName()); + } + } + @SuppressWarnings("deprecation") @Override public boolean isPathfindable(@NotNull BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull PathComputationType pType) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java index 03a30a68f..c6528d755 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java @@ -4,6 +4,7 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.ICopycatWithWrappedBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.decoration.copycat.CopycatBlock; @@ -32,6 +33,7 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; @@ -287,18 +289,38 @@ public static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) { return state; } - @SuppressWarnings("deprecation") @Override public @NotNull BlockState rotate(@NotNull BlockState state, Rotation rot) { + state = super.rotate(state, rot); return setApparentDirection(state, rot.rotate(getApparentDirection(state))); } @Override - @SuppressWarnings("deprecation") - public @NotNull BlockState mirror(BlockState state, Mirror mirrorIn) { + public void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation) { + Axis axis = state.getValue(AXIS); + if (axis == Axis.Y) return; + if (rotation == Rotation.CLOCKWISE_90 && axis == Axis.X || + rotation == Rotation.CLOCKWISE_180 || + rotation == Rotation.COUNTERCLOCKWISE_90 && axis == Axis.Z) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(Half.BOTTOM.getSerializedName()) ? Half.TOP.getSerializedName() : Half.BOTTOM.getSerializedName()); + } + } + + @Override + public @NotNull BlockState mirror(@NotNull BlockState state, Mirror mirrorIn) { + state = super.mirror(state, mirrorIn); return state.rotate(mirrorIn.getRotation(getApparentDirection(state))); } + @Override + public void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror) { + Axis axis = state.getValue(AXIS); + if (axis == Axis.Y) return; + if (mirror == Mirror.FRONT_BACK && axis == Axis.Z || mirror == Mirror.LEFT_RIGHT && axis == Axis.X) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(Half.BOTTOM.getSerializedName()) ? Half.TOP.getSerializedName() : Half.BOTTOM.getSerializedName()); + } + } + /** * Return the area of the face that is at the edge of the block. */ diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlock.java index fcfaae737..977f25968 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlock.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.test_block; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -10,10 +11,13 @@ import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; @@ -22,6 +26,9 @@ import java.util.Set; +import static com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock.getApparentDirection; +import static com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock.setApparentDirection; + public class CopycatTestBlock extends MultiStateCopycatBlock { public static final EnumProperty SLAB_TYPE = BlockStateProperties.SLAB_TYPE; @@ -162,4 +169,36 @@ public boolean canConnectTexturesToward(String property, BlockAndTintGetter read } return toState.is(this); } + + @Override + public @NotNull BlockState rotate(@NotNull BlockState state, Rotation rot) { + state = super.rotate(state, rot); + return setApparentDirection(state, rot.rotate(getApparentDirection(state))); + } + + @Override + public void rotate(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Rotation rotation) { + Direction.Axis axis = state.getValue(AXIS); + if (axis == Direction.Axis.Y) return; + if (rotation == Rotation.CLOCKWISE_90 && axis == Direction.Axis.X || + rotation == Rotation.CLOCKWISE_180 || + rotation == Rotation.COUNTERCLOCKWISE_90 && axis == Direction.Axis.Z) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(Half.BOTTOM.getSerializedName()) ? Half.TOP.getSerializedName() : Half.BOTTOM.getSerializedName()); + } + } + + @Override + public @NotNull BlockState mirror(@NotNull BlockState state, Mirror mirrorIn) { + state = super.mirror(state, mirrorIn); + return state.rotate(mirrorIn.getRotation(getApparentDirection(state))); + } + + @Override + public void mirror(@NotNull BlockState state, @NotNull MultiStateCopycatBlockEntity be, Mirror mirror) { + Direction.Axis axis = state.getValue(AXIS); + if (axis == Direction.Axis.Y) return; + if (mirror == Mirror.FRONT_BACK && axis == Direction.Axis.Z || mirror == Mirror.LEFT_RIGHT && axis == Direction.Axis.X) { + be.getMaterialItemStorage().remapStorage(s -> s.equals(Half.BOTTOM.getSerializedName()) ? Half.TOP.getSerializedName() : Half.BOTTOM.getSerializedName()); + } + } } From 9339880ead81c209b56e00892db8fd8051966032 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 11:43:52 +0800 Subject: [PATCH 16/71] Exclude model readme from build, fixes #11 --- build.gradle | 4 ++++ .../assets/copycats/models/block/copycat_base/README.md | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c37c4dedc..1dbe75ba3 100644 --- a/build.gradle +++ b/build.gradle @@ -102,6 +102,10 @@ allprojects { options.release.set(17) } + jar { + processResources.exclude("assets/copycats/models/block/copycat_base/README.md") + } + tasks.named('processResources', ProcessResources).configure { duplicatesStrategy(DuplicatesStrategy.EXCLUDE) // include packs diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/README.md b/common/src/main/resources/assets/copycats/models/block/copycat_base/README.md index b8ca6cffb..091f8587b 100644 --- a/common/src/main/resources/assets/copycats/models/block/copycat_base/README.md +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/README.md @@ -13,4 +13,11 @@ considerations need to be made when you want your model to function as a copycat - UVs on different faces of the same element must preserve their relative location to each other. - Basically, this means that the element must appear to be cut from the same corner of a block on all faces, so you cannot have an element which appears to come from the top of a block on one side, and the bottom of a block on the - opposite side. \ No newline at end of file + opposite side. + +However, copycat models are also more capable than regular block models in some ways: + +- Rotations, translations, and scaling can be done in all three axis and are not limited to 90-degree increments. +- Per-vertex translation and rotation can be used to create more complex shapes. + +For more info, see the documentation of the copycat assembly API: https://github.com/copycats-plus/copycats/blob/multiloader/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java \ No newline at end of file From 74a335c202f1a44f9e868af5ff274a804540b96e Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 12:24:39 +0800 Subject: [PATCH 17/71] Configure is_test_build in gradle.properties --- build.gradle | 2 +- gradle.properties | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1dbe75ba3..313f5c5fb 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { id 'org.ajoberstar.grgit' version '4.1.1' } -boolean isTestBuild = false; +boolean isTestBuild = rootProject.is_test_build.toBoolean() project.ext { // Open the Git repository in the current directory. diff --git a/gradle.properties b/gradle.properties index 375e18911..9010ac223 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,6 +3,7 @@ org.gradle.jvmargs=-Xmx3G #Mod archives_base_name=Copycats mod_version=1.3.4 +is_test_build=false maven_group=com.copycatsplus mod_authors=Lysine, Bennyboy1695, Redcat_XVIII # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. From 5755091363af2ee603970c9a70a80d64696e670a Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 12:27:18 +0800 Subject: [PATCH 18/71] Do a synchronized copy of the materials map to avoid concurrent exceptions in #63 --- .../multistate/fabric/MultiStateCopycatModel.java | 10 ++++++---- .../model/multistate/forge/MultiStateCopycatModel.java | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java index c511ff360..c980382b7 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java @@ -37,8 +37,6 @@ public abstract class MultiStateCopycatModel extends ForwardingBakedModel implements CustomParticleIconModel { - @NotNull Map materials = new HashMap<>(); - public MultiStateCopycatModel(BakedModel originalModel) { wrapped = originalModel; } @@ -69,13 +67,17 @@ private void gatherOcclusionData(BlockAndTintGetter world, BlockPos pos, BlockSt } } + @SuppressWarnings({"deprecation", "unchecked"}) @Override public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + Map materials; if (blockView instanceof RenderAttachedBlockView attachmentView && attachmentView.getBlockEntityRenderAttachment(pos) instanceof Map mats) { - materials = (Map) mats; + synchronized (mats) { + materials = new HashMap<>((Map) mats); + } } else { - materials = new HashMap<>(); + materials = Map.of(); } if (materials.isEmpty()) { if (state.getBlock() instanceof MultiStateCopycatBlock copycatBlock) { diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java index 2818fd51e..71c74bd9a 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java @@ -40,7 +40,7 @@ protected ModelData.Builder gatherModelData(ModelData.Builder builder, BlockAndT if (material.isEmpty()) return builder; - builder.with(MATERIALS_PROPERTY, material); + builder.with(MATERIALS_PROPERTY, new HashMap<>(material)); if (!(state.getBlock() instanceof MultiStateCopycatBlock copycatBlock)) return builder; From b9faac3f5ac71bdaf48265389724b63451d11344 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 13:07:15 +0800 Subject: [PATCH 19/71] Fix CT on copycat boards --- .../copycat/base/multistate/MultiStateCopycatBlock.java | 4 ++++ .../copycat/base/multistate/ScaledBlockAndTintGetter.java | 8 +++++++- .../copycats/content/copycat/board/CopycatBoardBlock.java | 6 ++++++ .../model/multistate/fabric/MultiStateCopycatModel.java | 4 ++-- .../multistate/fabric/MultiStateCopycatBlockImpl.java | 3 +-- .../model/multistate/forge/MultiStateCopycatModel.java | 4 ++-- .../multistate/forge/ScaledBlockAndTintGetterForge.java | 5 +++-- .../base/multistate/forge/MultiStateCopycatBlockImpl.java | 2 +- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java index b7c1f15c7..b16aba27e 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java @@ -89,6 +89,10 @@ protected void createBlockStateDefinition(StateDefinition.Builder filter; - public ScaledBlockAndTintGetter(BlockAndTintGetter wrapped, BlockPos origin, Vec3i originInner, Vec3i scale, Predicate filter) { + public ScaledBlockAndTintGetter(String renderingProperty, BlockAndTintGetter wrapped, BlockPos origin, Vec3i originInner, Vec3i scale, Predicate filter) { + this.renderingProperty = renderingProperty; this.wrapped = wrapped; this.origin = origin; this.originInner = originInner; @@ -31,6 +33,10 @@ public ScaledBlockAndTintGetter(BlockAndTintGetter wrapped, BlockPos origin, Vec this.filter = filter; } + public String getRenderingProperty() { + return renderingProperty; + } + public BlockAndTintGetter getWrapped() { return wrapped; } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java index cf219da17..69cd3611c 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java @@ -5,6 +5,7 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MaterialItemStorage; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.google.common.collect.ImmutableMap; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Iterate; @@ -98,6 +99,11 @@ public String getPropertyFromInteraction(BlockState state, BlockGetter level, Ve return face.getName(); } + @Override + public String getPropertyFromRender(String renderingProperty, BlockState state, ScaledBlockAndTintGetter level, Vec3i vector, BlockPos blockPos, Direction side, BlockState queryState, BlockPos queryPos) { + return renderingProperty; + } + @Override public Vec3i getVectorFromProperty(BlockState state, String property) { return Vec3i.ZERO; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java index c980382b7..ea1c85c24 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java @@ -111,8 +111,8 @@ public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, Block BlockAndTintGetter innerBlockView = blockView; if (state.getBlock() instanceof MultiStateCopycatBlock copycatBlock) { Vec3i inner = copycatBlock.getVectorFromProperty(state, entry.getKey()); - ScaledBlockAndTintGetter scaledWorld = new ScaledBlockAndTintGetter(blockView, pos, inner, copycatBlock.vectorScale(state), p -> true); - innerBlockView = new ScaledBlockAndTintGetter(blockView, pos, inner, copycatBlock.vectorScale(state), + ScaledBlockAndTintGetter scaledWorld = new ScaledBlockAndTintGetter(entry.getKey(), blockView, pos, inner, copycatBlock.vectorScale(state), p -> true); + innerBlockView = new ScaledBlockAndTintGetter(entry.getKey(), blockView, pos, inner, copycatBlock.vectorScale(state), targetPos -> copycatBlock.canConnectTexturesToward(entry.getKey(), scaledWorld, pos, targetPos, state)); } emitBlockQuadsInner(entry.getKey(), innerBlockView, state, pos, randomSupplier, context, entry.getValue(), cullFaceRemovalData, occlusionData); diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java index a03e6d892..2b960439d 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java @@ -73,7 +73,6 @@ public static VoxelShape multiPlatformGetShape(@NotNull BlockState pState, @NotN return null; } - @SuppressWarnings("UnstableApiUsage") public static BlockState multiPlatformGetAppearance(MultiStateCopycatBlock block, BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, BlockState queryState, BlockPos queryPos) { String property; @@ -81,7 +80,7 @@ public static BlockState multiPlatformGetAppearance(MultiStateCopycatBlock block if (level instanceof ScaledBlockAndTintGetter scaledLevel) { truePos = scaledLevel.getTruePos(pos); Vec3i inner = scaledLevel.getInner(pos); - property = block.getPropertyFromInteraction(state, level, inner, truePos, side, Vec3.atCenterOf(inner)); + property = block.getPropertyFromRender(scaledLevel.getRenderingProperty(), state, scaledLevel, inner, truePos, side, queryState, queryPos); } else { property = block.storageProperties().stream().findFirst().get(); } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java index 71c74bd9a..f1ca931c8 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java @@ -55,8 +55,8 @@ protected ModelData.Builder gatherModelData(ModelData.Builder builder, BlockAndT Map wrappedDataMap = material.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, s -> { Vec3i inner = copycatBlock.getVectorFromProperty(state, s.getKey()); - ScaledBlockAndTintGetterForge scaledWorld = new ScaledBlockAndTintGetterForge(world, pos, inner, copycatBlock.vectorScale(state), p -> true); - ScaledBlockAndTintGetterForge filteredWorld = new ScaledBlockAndTintGetterForge(world, pos, inner, copycatBlock.vectorScale(state), + ScaledBlockAndTintGetterForge scaledWorld = new ScaledBlockAndTintGetterForge(s.getKey(), world, pos, inner, copycatBlock.vectorScale(state), p -> true); + ScaledBlockAndTintGetterForge filteredWorld = new ScaledBlockAndTintGetterForge(s.getKey(), world, pos, inner, copycatBlock.vectorScale(state), targetPos -> copycatBlock.canConnectTexturesToward(s.getKey(), scaledWorld, pos, targetPos, state)); return getModelOf(s.getValue()).getModelData( filteredWorld, diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/ScaledBlockAndTintGetterForge.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/ScaledBlockAndTintGetterForge.java index 09c7e9172..fcee42dd0 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/ScaledBlockAndTintGetterForge.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/ScaledBlockAndTintGetterForge.java @@ -10,8 +10,9 @@ import java.util.function.Predicate; public class ScaledBlockAndTintGetterForge extends ScaledBlockAndTintGetter { - public ScaledBlockAndTintGetterForge(BlockAndTintGetter wrapped, BlockPos origin, Vec3i originInner, Vec3i scale, Predicate filter) { - super(wrapped, origin, originInner, scale, filter); + + public ScaledBlockAndTintGetterForge(String renderingProperty, BlockAndTintGetter wrapped, BlockPos origin, Vec3i originInner, Vec3i scale, Predicate filter) { + super(renderingProperty, wrapped, origin, originInner, scale, filter); } @SuppressWarnings("UnstableApiUsage") diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java index acf03575d..381263e72 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java @@ -36,7 +36,7 @@ public static BlockState multiPlatformGetAppearance(MultiStateCopycatBlock block if (level instanceof ScaledBlockAndTintGetter scaledLevel) { truePos = scaledLevel.getTruePos(pos); Vec3i inner = scaledLevel.getInner(pos); - property = block.getPropertyFromInteraction(state, level, inner, truePos, side, Vec3.atCenterOf(inner)); + property = block.getPropertyFromRender(scaledLevel.getRenderingProperty(), state, scaledLevel, inner, truePos, side, queryState, queryPos); } else { property = block.storageProperties().stream().findFirst().get(); } From ec13bad4d712332f47048b2273519a2daf75fda3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 14:43:35 +0800 Subject: [PATCH 20/71] Add feature categories --- .../com/copycatsplus/copycats/CCBlocks.java | 3 +- .../copycatsplus/copycats/config/CCommon.java | 5 +- .../copycats/config/CFeatureCategories.java | 78 +++++++++++++++++++ .../copycats/config/FeatureCategory.java | 32 ++++++++ .../copycats/config/FeatureToggle.java | 50 ++++++++++++ 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/config/CFeatureCategories.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index cc2a8a338..b0391aa07 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats; +import com.copycatsplus.copycats.config.FeatureCategory; import com.copycatsplus.copycats.config.FeatureToggle; import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.ToggleableCopycatModel; @@ -480,7 +481,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_SLOPE = REGISTRATE.block("copycat_slope", CopycatSlopeBlock::new) .transform(BuilderTransformers.copycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.SLOPES)) .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(), new CopycatSlopeEnhancedModel()))) .item() .transform(customItemModel("copycat_base", "slope")) diff --git a/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java b/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java index cdcd3b10f..e55d1ee26 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java @@ -21,14 +21,15 @@ public String getName() { public final CFeatures toggle = nested(0, CFeatures::new, Comments.toggle); + public final CFeatureCategories categories = nested(0, CFeatureCategories::new, Comments.categories); + public void register() { } private static class Comments { static String toggle = "Enable/disable features. Values on server override clients"; - + static String categories = "Enable/disable categories of features. Disabling a category hides all related features. Values on server override clients"; static String dataFixers = "Enables/Disables the data fixers. (Currently none available)"; - static String multiStateConversion = "Enables/Disables the conversion of placed copycats from the single material to the multi material(where applicable) block entity. Set this to false to enable conversion! (only happens on world load, so if changed while ingame you will need to load the world again)"; } } diff --git a/common/src/main/java/com/copycatsplus/copycats/config/CFeatureCategories.java b/common/src/main/java/com/copycatsplus/copycats/config/CFeatureCategories.java new file mode 100644 index 000000000..409384c35 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/config/CFeatureCategories.java @@ -0,0 +1,78 @@ +package com.copycatsplus.copycats.config; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.config.ModConfig; +import org.jetbrains.annotations.ApiStatus; + +import java.util.HashMap; +import java.util.Map; + +/** + * Configures all feature categories. + * Values in this class should NOT be accessed directly. Please access via {@link FeatureToggle} instead. + */ +public class CFeatureCategories extends SyncConfigBase { + + @Override + public String getName() { + return "feature_categories"; + } + + final Map> toggles = new HashMap<>(); + + Map synchronizedToggles; + + @Override + public void registerAll(ForgeConfigSpec.Builder builder) { + for (FeatureCategory r : FeatureCategory.values()) { + builder.comment(".", r.getDescription()); + toggles.put(r, builder.define(r.getSerializedName(), true)); + } + } + + @ApiStatus.Internal + public boolean isEnabled(FeatureCategory category) { + if (this.synchronizedToggles != null) { + Boolean synced = synchronizedToggles.get(category); + if (synced != null) return synced; + } + ForgeConfigSpec.ConfigValue value = toggles.get(category); + if (value != null) + return value.get(); + return true; + } + + @Override + public void onLoad() { + super.onLoad(); + FeatureToggle.refreshItemVisibility(); + } + + @Override + public void onReload() { + super.onReload(); + FeatureToggle.refreshItemVisibility(); + } + + @Override + protected void readSyncConfig(CompoundTag nbt) { + synchronizedToggles = new HashMap<>(); + for (String key : nbt.getAllKeys()) { + FeatureCategory category = FeatureCategory.byName(key); + synchronizedToggles.put(category, nbt.getBoolean(key)); + } + FeatureToggle.refreshItemVisibility(); + } + + @Override + protected ModConfig.Type type() { + return ModConfig.Type.COMMON; + } + + @Override + protected void writeSyncConfig(CompoundTag nbt) { + toggles.forEach((key, value) -> nbt.putBoolean(key.toString(), value.get())); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java b/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java new file mode 100644 index 000000000..ff3d823d9 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java @@ -0,0 +1,32 @@ +package com.copycatsplus.copycats.config; + +import net.minecraft.util.StringRepresentable; +import org.jetbrains.annotations.NotNull; + +public enum FeatureCategory implements StringRepresentable { + SLOPES("All copycats with a sloped surface"); + + private final String description; + + FeatureCategory(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } + + @Override + public @NotNull String getSerializedName() { + return this.name().toLowerCase(); + } + + public static FeatureCategory byName(String name) { + for (FeatureCategory category : values()) { + if (category.getSerializedName().equalsIgnoreCase(name)) { + return category; + } + } + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java b/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java index d36f68f4a..452353b95 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java @@ -19,15 +19,26 @@ public class FeatureToggle { public static final Set TOGGLEABLE_FEATURES = new HashSet<>(); public static final Map DEPENDENT_FEATURES = new HashMap<>(); + public static final Map FEATURE_CATEGORIES = new HashMap<>(); public static void register(ResourceLocation key) { TOGGLEABLE_FEATURES.add(key); } + public static void register(ResourceLocation key, FeatureCategory category) { + register(key); + FEATURE_CATEGORIES.put(key, category); + } + public static void registerDependent(ResourceLocation key, ResourceLocation dependency) { DEPENDENT_FEATURES.put(key, dependency); } + public static void registerDependent(ResourceLocation key, ResourceLocation dependency, FeatureCategory category) { + registerDependent(key, dependency); + FEATURE_CATEGORIES.put(key, category); + } + /** * Register this object to be a feature that is toggleable by the user */ @@ -38,6 +49,16 @@ public static > NonNullUnaryOpe }; } + /** + * Register this object to be a feature that is toggleable by the user + */ + public static > NonNullUnaryOperator register(FeatureCategory category) { + return b -> { + register(new ResourceLocation(b.getOwner().getModid(), b.getName()), category); + return b; + }; + } + /** * Register this object to be dependent on another feature. * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. @@ -49,6 +70,17 @@ public static > NonNullUnaryOpe }; } + /** + * Register this object to be dependent on another feature. + * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. + */ + public static > NonNullUnaryOperator registerDependent(ResourceLocation dependency, FeatureCategory category) { + return b -> { + registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency, category); + return b; + }; + } + /** * Register this object to be dependent on another feature. * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. @@ -60,10 +92,25 @@ public static > NonNullUnaryOpe }; } + /** + * Register this object to be dependent on another feature. + * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. + */ + public static > NonNullUnaryOperator registerDependent(BlockEntry dependency, FeatureCategory category) { + return b -> { + registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency.getId(), category); + return b; + }; + } + private static CFeatures getToggles() { return CCConfigs.common().toggle; } + private static CFeatureCategories getCategories() { + return CCConfigs.common().categories; + } + /** * Check whether a feature is enabled. * If the provided {@link ResourceLocation} is not registered with this feature toggle, it is assumed to be enabled. @@ -72,6 +119,9 @@ private static CFeatures getToggles() { * @return Whether the feature is enabled. */ public static boolean isEnabled(ResourceLocation key) { + if (FEATURE_CATEGORIES.containsKey(key)) { + if (!getCategories().isEnabled(FEATURE_CATEGORIES.get(key))) return false; + } if (getToggles().hasToggle(key)) { return getToggles().isEnabled(key); } else { From 04f8eb5d1e81eda14ce6e65b6ccf3f4a8052351b Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 14:54:58 +0800 Subject: [PATCH 21/71] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daff8bbe1..c1b76672b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 1.3.4 - 2024-06-19 -## Fixed +### Fixed - Multistate copycats having much lower friction than normal From 60a8b3e97176728c1cb835903c52d7a69e78f048 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 17:47:36 +0800 Subject: [PATCH 22/71] Add vertical slopes and improve slope models and CT --- .../copycats/CCBlockEntityTypes.java | 8 +- .../com/copycatsplus/copycats/CCBlocks.java | 14 +- .../copycatsplus/copycats/CCCreativeTabs.java | 3 +- .../com/copycatsplus/copycats/CCShapes.java | 8 + .../base/model/assembly/Assembler.java | 8 + .../base/model/assembly/MutableQuad.java | 8 +- .../copycat/base/model/assembly/Mutation.java | 121 ++++++++ .../assembly/quad/QuadLightDirection.java | 16 + .../copycat/slope/CopycatSlopeBlock.java | 60 ++-- .../slope/CopycatSlopeEnhancedModel.java | 102 ------- .../copycat/slope/CopycatSlopeModel.java | 104 ++++++- .../CopycatVerticalSlopeBlock.java | 273 ++++++++++++++++++ .../CopycatVerticalSlopeModel.java | 37 +++ .../datagen/recipes/CCStandardRecipes.java | 2 + .../block/copycat_base/vertical_slope.json | 38 +++ .../blockstates/copycat_vertical_slope.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../models/item/copycat_vertical_slope.json | 3 + .../stonecutting/copycat_vertical_slope.json | 33 +++ .../blocks/copycat_vertical_slope.json | 21 ++ .../stonecutting/copycat_vertical_slope.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../model/assembly/fabric/AssemblerImpl.java | 3 +- .../blockstates/copycat_vertical_slope.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../models/item/copycat_vertical_slope.json | 3 + .../stonecutting/copycat_vertical_slope.json | 33 +++ .../blocks/copycat_vertical_slope.json | 21 ++ .../stonecutting/copycat_vertical_slope.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../model/assembly/forge/AssemblerImpl.java | 9 +- 35 files changed, 816 insertions(+), 158 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadLightDirection.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java create mode 100644 common/src/main/resources/assets/copycats/models/block/copycat_base/vertical_slope.json create mode 100644 fabric/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json create mode 100644 fabric/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json create mode 100644 fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json create mode 100644 forge/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json create mode 100644 forge/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json create mode 100644 forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json create mode 100644 forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json create mode 100644 forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java index b35743d8a..debb999ce 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java @@ -14,7 +14,6 @@ public class CCBlockEntityTypes { REGISTRATE.blockEntity("copycat", CopycatBlockEntity::new) .validBlocks( CCBlocks.COPYCAT_BLOCK, - /* CCBlocks.COPYCAT_SLAB,*/ CCBlocks.COPYCAT_BEAM, CCBlocks.COPYCAT_VERTICAL_STEP, CCBlocks.COPYCAT_HALF_PANEL, @@ -23,12 +22,9 @@ public class CCBlockEntityTypes { CCBlocks.COPYCAT_FENCE_GATE, CCBlocks.COPYCAT_TRAPDOOR, CCBlocks.COPYCAT_WALL, -/* CCBlocks.COPYCAT_BOARD,*/ - /* CCBlocks.COPYCAT_BYTE,*/ CCBlocks.COPYCAT_GHOST_BLOCK, CCBlocks.COPYCAT_LADDER, CCBlocks.COPYCAT_LAYER, -/* CCBlocks.COPYCAT_HALF_LAYER,*/ CCBlocks.COPYCAT_SLICE, CCBlocks.COPYCAT_VERTICAL_SLICE, CCBlocks.COPYCAT_WOODEN_BUTTON, @@ -37,7 +33,9 @@ public class CCBlockEntityTypes { CCBlocks.COPYCAT_STONE_PRESSURE_PLATE, CCBlocks.COPYCAT_LIGHT_WEIGHTED_PRESSURE_PLATE, CCBlocks.COPYCAT_HEAVY_WEIGHTED_PRESSURE_PLATE, - CCBlocks.COPYCAT_VERTICAL_STAIRS + CCBlocks.COPYCAT_VERTICAL_STAIRS, + CCBlocks.COPYCAT_SLOPE, + CCBlocks.COPYCAT_VERTICAL_SLOPE ) .register(); diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index b0391aa07..f087043f9 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -41,7 +41,6 @@ import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceBlock; import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceModel; import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeBlock; -import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeEnhancedModel; import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsBlock; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsEnhancedModel; @@ -54,6 +53,8 @@ import com.copycatsplus.copycats.content.copycat.trapdoor.WrappedTrapdoorBlock; import com.copycatsplus.copycats.content.copycat.vertical_slice.CopycatVerticalSliceBlock; import com.copycatsplus.copycats.content.copycat.vertical_slice.CopycatVerticalSliceModel; +import com.copycatsplus.copycats.content.copycat.vertical_slope.CopycatVerticalSlopeBlock; +import com.copycatsplus.copycats.content.copycat.vertical_slope.CopycatVerticalSlopeModel; import com.copycatsplus.copycats.content.copycat.vertical_stairs.CopycatVerticalStairBlock; import com.copycatsplus.copycats.content.copycat.vertical_stairs.CopycatVerticalStairsEnhancedModel; import com.copycatsplus.copycats.content.copycat.vertical_stairs.CopycatVerticalStairsModel; @@ -482,11 +483,20 @@ public class CCBlocks { REGISTRATE.block("copycat_slope", CopycatSlopeBlock::new) .transform(BuilderTransformers.copycat()) .transform(FeatureToggle.register(FeatureCategory.SLOPES)) - .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(), new CopycatSlopeEnhancedModel()))) + .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(false), new CopycatSlopeModel(true)))) .item() .transform(customItemModel("copycat_base", "slope")) .register(); + public static final BlockEntry COPYCAT_VERTICAL_SLOPE = + REGISTRATE.block("copycat_vertical_slope", CopycatVerticalSlopeBlock::new) + .transform(BuilderTransformers.copycat()) + .transform(FeatureToggle.register(FeatureCategory.SLOPES)) + .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatVerticalSlopeModel(false), new CopycatVerticalSlopeModel(true)))) + .item() + .transform(customItemModel("copycat_base", "vertical_slope")) + .register(); + public static @Nullable BlockEntry COPYCAT_TEST_BLOCK; @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index 9e8fb1f21..c1343ea20 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -39,7 +39,8 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_WALL, CCBlocks.COPYCAT_WOODEN_BUTTON, CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, - CCBlocks.COPYCAT_SLOPE + CCBlocks.COPYCAT_SLOPE, + CCBlocks.COPYCAT_VERTICAL_SLOPE ); @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java index 8e4a47f1a..238f1ab72 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java @@ -154,6 +154,14 @@ public class CCShapes { shape = shape.optimize(); return shape(shape).forDirectional(Direction.NORTH); }, Direction.SOUTH); + public static final VoxelShaper SLOPE_LEFT = shape(Shapes.empty()).build((voxelShape, direction) -> { + VoxelShape shape = Shapes.empty(); + for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(1 - 1d / SLOPE_SUBDIVISIONS * (i + 1), 0, 1d / SLOPE_SUBDIVISIONS * i, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + } + shape = shape.optimize(); + return shape(shape).forDirectional(Direction.SOUTH); + }, Direction.SOUTH); private static Builder shape(VoxelShape shape) { return new Builder(shape); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java index f8a89bff5..a7bd1aac6 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Assembler.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Objects; +import java.util.function.Function; public class Assembler { @@ -210,6 +211,13 @@ public static QuadUVUpdate updateUV(QuadTransform... transforms) { return new QuadUVUpdate(transforms); } + /** + * Modify the lighting direction of the quad. + */ + public static QuadLightDirection lightDirection(Function directionMapper) { + return new QuadLightDirection(directionMapper); + } + public static class CopycatRenderContext { private final Source source; private final Destination destination; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java index 2637888b8..a897bd00b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/MutableQuad.java @@ -1,14 +1,18 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; +import net.minecraft.core.Direction; + import java.util.ArrayList; import java.util.List; public class MutableQuad implements GlobalTransform.Transformable { public List vertices; + public Direction direction; List mutations = new ArrayList<>(); - public MutableQuad(List vertices) { + public MutableQuad(List vertices, Direction direction) { this.vertices = vertices; + this.direction = direction; } public MutableQuad mutate() { @@ -16,6 +20,7 @@ public MutableQuad mutate() { for (MutableVertex vertex : vertices) { mutation.mutate(vertex.xyz); } + direction = mutation.mutate(direction); } return this; } @@ -26,6 +31,7 @@ public MutableQuad undoMutate() { for (MutableVertex vertex : vertices) { mutation.undoMutate(vertex.xyz); } + direction = mutation.undoMutate(direction); } return this; } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Mutation.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Mutation.java index 62633e82d..9df64b2ba 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Mutation.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/Mutation.java @@ -1,6 +1,9 @@ package com.copycatsplus.copycats.content.copycat.base.model.assembly; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; + public record Mutation(MutationType type, int value) { public > T mutate(T vec3) { return switch (type) { @@ -16,6 +19,20 @@ public > T mutate(T vec3) { }; } + public Direction mutate(Direction dir) { + return switch (type) { + case ROTATE_X -> rotateX(dir, value); + case ROTATE_Y -> rotateY(dir, value); + case ROTATE_Z -> rotateZ(dir, value); + case MIRROR -> { + if (value == 0 && dir.getAxis() == Axis.X) yield dir.getOpposite(); + else if (value == 1 && dir.getAxis() == Axis.Y) yield dir.getOpposite(); + else if (value == 2 && dir.getAxis() == Axis.Z) yield dir.getOpposite(); + else yield dir; + } + }; + } + public > T undoMutate(T vec3) { return switch (type) { case ROTATE_X -> vec3.rotateX(-value); @@ -30,6 +47,110 @@ public > T undoMutate(T vec3) { }; } + public Direction undoMutate(Direction dir) { + return switch (type) { + case ROTATE_X -> rotateX(dir, -value); + case ROTATE_Y -> rotateY(dir, -value); + case ROTATE_Z -> rotateZ(dir, -value); + case MIRROR -> { + if (value == 0 && dir.getAxis() == Axis.X) yield dir.getOpposite(); + else if (value == 1 && dir.getAxis() == Axis.Y) yield dir.getOpposite(); + else if (value == 2 && dir.getAxis() == Axis.Z) yield dir.getOpposite(); + else yield dir; + } + }; + } + + private static Direction rotateX(Direction dir, int angle) { + // rotate around the X axis clockwise + angle = angle % 360; + if (angle < 0) angle += 360; + return switch (angle) { + case 90 -> switch (dir) { + case NORTH -> Direction.DOWN; + case SOUTH -> Direction.UP; + case UP -> Direction.NORTH; + case DOWN -> Direction.SOUTH; + default -> dir; + }; + case 180 -> switch (dir) { + case NORTH -> Direction.SOUTH; + case SOUTH -> Direction.NORTH; + case UP -> Direction.DOWN; + case DOWN -> Direction.UP; + default -> dir; + }; + case 270 -> switch (dir) { + case NORTH -> Direction.UP; + case SOUTH -> Direction.DOWN; + case UP -> Direction.SOUTH; + case DOWN -> Direction.NORTH; + default -> dir; + }; + default -> dir; + }; + } + + private static Direction rotateY(Direction dir, int angle) { + // rotate around the Y axis clockwise + angle = angle % 360; + if (angle < 0) angle += 360; + return switch (angle) { + case 90 -> switch (dir) { + case NORTH -> Direction.EAST; + case SOUTH -> Direction.WEST; + case EAST -> Direction.SOUTH; + case WEST -> Direction.NORTH; + default -> dir; + }; + case 180 -> switch (dir) { + case NORTH -> Direction.SOUTH; + case SOUTH -> Direction.NORTH; + case EAST -> Direction.WEST; + case WEST -> Direction.EAST; + default -> dir; + }; + case 270 -> switch (dir) { + case NORTH -> Direction.WEST; + case SOUTH -> Direction.EAST; + case EAST -> Direction.NORTH; + case WEST -> Direction.SOUTH; + default -> dir; + }; + default -> dir; + }; + } + + private static Direction rotateZ(Direction dir, int angle) { + // rotate around the Z axis clockwise + angle = angle % 360; + if (angle < 0) angle += 360; + return switch (angle) { + case 90 -> switch (dir) { + case UP -> Direction.EAST; + case DOWN -> Direction.WEST; + case EAST -> Direction.DOWN; + case WEST -> Direction.UP; + default -> dir; + }; + case 180 -> switch (dir) { + case UP -> Direction.DOWN; + case DOWN -> Direction.UP; + case EAST -> Direction.WEST; + case WEST -> Direction.EAST; + default -> dir; + }; + case 270 -> switch (dir) { + case UP -> Direction.WEST; + case DOWN -> Direction.EAST; + case EAST -> Direction.UP; + case WEST -> Direction.DOWN; + default -> dir; + }; + default -> dir; + }; + } + public enum MutationType { ROTATE_X, ROTATE_Y, diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadLightDirection.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadLightDirection.java new file mode 100644 index 000000000..1fe183f31 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/quad/QuadLightDirection.java @@ -0,0 +1,16 @@ +package com.copycatsplus.copycats.content.copycat.base.model.assembly.quad; + +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableQuad; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableVec3; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.Direction; + +import java.util.function.Function; + +public record QuadLightDirection(Function directionMapper) implements QuadTransform { + + @Override + public void transformVertices(MutableQuad quad, TextureAtlasSprite sprite) { + quad.direction = directionMapper.apply(quad.direction); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java index 1650c5089..7e6a9dce9 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -1,29 +1,15 @@ package com.copycatsplus.copycats.content.copycat.slope; -import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.copycatsplus.copycats.content.copycat.base.IStateType; -import com.simibubi.create.content.equipment.extendoGrip.ExtendoGripItem; -import com.simibubi.create.foundation.placement.IPlacementHelper; -import com.simibubi.create.foundation.placement.PlacementHelpers; -import com.simibubi.create.foundation.placement.PlacementOffset; -import com.simibubi.create.foundation.placement.PoleHelper; -import com.simibubi.create.infrastructure.config.AllConfigs; -import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.ai.attributes.AttributeInstance; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; @@ -34,17 +20,13 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.pathfinder.PathComputationType; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.NotNull; -import java.util.List; -import java.util.function.Predicate; +import java.util.Optional; -public class CopycatSlopeBlock extends CTWaterloggedCopycatBlock implements IStateType { +public class CopycatSlopeBlock extends CTWaterloggedCopycatBlock implements IStateType, ICustomCTBlocking { public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final EnumProperty HALF = BlockStateProperties.HALF; @@ -64,21 +46,20 @@ public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState s Half half = state.getValue(HALF); BlockState toState = reader.getBlockState(toPos); - if (toState.is(this)) { - if (toState.getValue(FACING) == direction && toState.getValue(HALF)== half) return false; - - BlockPos diff = toPos.subtract(fromPos); - if (diff.equals(Vec3i.ZERO)) { - return false; - } - Direction connectFace = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); - if (connectFace == null) { - return true; - } + BlockPos diff = toPos.subtract(fromPos); + if (diff.equals(Vec3i.ZERO)) { + return false; + } + Direction connectFace = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (connectFace == null) { + return false; + } + if (toState.is(this)) { + if (toState.getValue(FACING) == direction && toState.getValue(HALF) == half) return false; return !(direction == connectFace && connectFace == toState.getValue(FACING).getOpposite()); } else { - return false; + return !(direction == connectFace || half == Half.TOP && connectFace == Direction.UP || half == Half.BOTTOM && connectFace == Direction.DOWN); } } @@ -86,7 +67,6 @@ public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState s public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, BlockState state) { BlockState toState = reader.getBlockState(toPos); - if (!toState.is(this)) return false; Direction facing = state.getValue(FACING); Half half = state.getValue(HALF); @@ -96,7 +76,7 @@ public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos from } Direction face = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); if (face == null) { - return false; + return true; } if (toState.is(this)) { @@ -109,8 +89,16 @@ public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos from return false; } } else { - return false; + return face == facing || half == Half.TOP && face == Direction.UP || half == Half.BOTTOM && face == Direction.DOWN; + } + } + + @Override + public Optional isCTBlocked(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos connectingPos, BlockPos blockingPos, Direction face) { + if (reader.getBlockState(blockingPos).is(this)) { + return Optional.of(false); } + return Optional.empty(); } @SuppressWarnings("deprecation") diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java deleted file mode 100644 index 23e182395..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeEnhancedModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.slope; - -import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Half; - -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.QuadSlope.map; - -public class CopycatSlopeEnhancedModel implements SimpleCopycatPart { - - private static final double MARGIN = 2; - private static final double MARGIN_ADJ = MARGIN / Math.tan(Math.toRadians(22.5)); - private static final double MID_LENGTH = 16 * Math.sqrt(2) - 2 * MARGIN_ADJ; - private static final double ALIGNED_LENGTH = ((int) Math.floor(MID_LENGTH)) % 2 == 0 ? Math.floor(MID_LENGTH) : Math.floor(MID_LENGTH) + 1; - - @Override - public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { - Direction facing = state.getValue(CopycatSlopeBlock.FACING); - Half half = state.getValue(CopycatSlopeBlock.HALF); - int rot = (int) facing.toYRot(); - boolean flipY = half == Half.TOP; - GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); - assemblePiece(context, - transform, - vec3(0, 0, 0), - aabb(16, 16, MARGIN_ADJ), - cull(UP | NORTH | SOUTH), - updateUV(slope(Direction.UP, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b))) - ); - assemblePiece(context, - transform, - vec3(0, 0, MARGIN_ADJ), - aabb(16, 16, 16 - MARGIN - MARGIN_ADJ).move(0, 0, MARGIN_ADJ), - cull(UP | NORTH | SOUTH), - updateUV(slope(Direction.UP, (a, b) -> map(MARGIN_ADJ, 16 - MARGIN, MARGIN, 16 - MARGIN_ADJ, b))) - ); - assemblePiece(context, - transform, - vec3(0, 0, 16 - MARGIN), - aabb(16, 16, MARGIN).move(0, 0, 16 - MARGIN), - cull(UP | NORTH), - updateUV(slope(Direction.UP, (a, b) -> map(16 - MARGIN, 16, 16 - MARGIN_ADJ, 16, b))) - ); - assemblePiece(context, - transform, - vec3(0, 0, 0), - aabb(16, 16, MARGIN_ADJ), - cull(DOWN | NORTH | SOUTH), - updateUV(slope(Direction.DOWN, (a, b) -> map(0, MARGIN_ADJ, 0, MARGIN, b))), - translate(0, -16, 0), - rotate( - pivot(0, 0, 0), - angle(-45, 0, 0) - ) - ); - assemblePiece(context, - transform, - vec3(0, 16 - MARGIN, 16 - ALIGNED_LENGTH / 2), - aabb(16, MARGIN, ALIGNED_LENGTH / 2).move(0, 16 - MARGIN, Math.floor((16 - ALIGNED_LENGTH / 2) / 2)), - cull(DOWN | NORTH | SOUTH), - scale( - pivot(16, 16, 16), - scale(1, 1, MID_LENGTH / ALIGNED_LENGTH) - ), - translate(0, 0, -MARGIN_ADJ - MID_LENGTH / 2), - rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) - ) - ); - assemblePiece(context, - transform, - vec3(0, 16 - MARGIN, 16 - ALIGNED_LENGTH / 2), - aabb(16, MARGIN, ALIGNED_LENGTH / 2).move(0, 16 - MARGIN, Math.floor((16 - ALIGNED_LENGTH / 2) / 2)), - cull(DOWN | NORTH | SOUTH), - scale( - pivot(16, 16, 16), - scale(1, 1, MID_LENGTH / ALIGNED_LENGTH) - ), - translate(0, 0, -MARGIN_ADJ), - rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) - ) - ); - assemblePiece(context, - transform, - vec3(0, 0, 16 - MARGIN_ADJ), - aabb(16, 16, MARGIN_ADJ).move(0, 0, 16 - MARGIN_ADJ), - cull(DOWN | NORTH | SOUTH), - updateUV(slope(Direction.DOWN, (a, b) -> map(16 - MARGIN_ADJ, 16, MARGIN, 0, b))), - rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) - ) - ); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java index d43f3fd5c..1365dda3e 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -7,10 +7,18 @@ import net.minecraft.world.level.block.state.properties.Half; import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; -import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.NORTH; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.SOUTH; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.quad.QuadSlope.map; public class CopycatSlopeModel implements SimpleCopycatPart { + private final boolean enhanced; + + public CopycatSlopeModel(boolean enhanced) { + this.enhanced = enhanced; + } + @Override public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { Direction facing = state.getValue(CopycatSlopeBlock.FACING); @@ -18,12 +26,104 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex int rot = (int) facing.toYRot(); boolean flipY = half == Half.TOP; GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); + if (enhanced) + assembleSlope(context, transform, 16, 0, 3); + else + assembleSlope(context, transform, 16, 0); + } + + public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double minHeight) { assemblePiece(context, transform, vec3(0, 0, 0), aabb(16, 16, 16), cull(NORTH), - updateUV(slope(Direction.UP, (a, b) -> b)) + updateUV(slope(Direction.UP, (a, b) -> map(0, 16, minHeight, maxHeight, b))) + ); + } + + public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double minHeight, double margin) { + final double angle = Math.atan2(maxHeight - minHeight, 16) / 2; + final double marginAdj = margin / Math.tan(angle); + final double midLength = Math.sqrt((maxHeight - minHeight) * (maxHeight - minHeight) + 16 * 16) - 2 * marginAdj; + final double marginAdjExcess = marginAdj - Math.floor(marginAdj); + final double alignedLength = ((int) Math.floor(midLength + 2 * marginAdjExcess)) % 2 == 0 + ? Math.floor(midLength + 2 * marginAdjExcess) - 2 * marginAdjExcess + : Math.floor(midLength + 2 * marginAdjExcess) + 1 - 2 * marginAdjExcess; + + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, marginAdj), + cull(UP | NORTH | SOUTH), + updateUV(slope(Direction.UP, (a, b) -> map(0, marginAdj, 0, margin, b))) + ); + assemblePiece(context, + transform, + vec3(0, 0, marginAdj), + aabb(16, 16, 16 - margin - marginAdj).move(0, 0, marginAdj), + cull(UP | NORTH | SOUTH), + updateUV(slope(Direction.UP, (a, b) -> map(marginAdj, 16 - margin, margin, 16 - marginAdj, b))) + ); + assemblePiece(context, + transform, + vec3(0, 0, 16 - margin), + aabb(16, 16, margin).move(0, 0, 16 - margin), + cull(UP | NORTH), + updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, 16 - marginAdj, 16, b))) + ); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, marginAdj), + cull(DOWN | NORTH | SOUTH), + updateUV(slope(Direction.DOWN, (a, b) -> map(0, marginAdj, 0, margin, b))), + translate(0, -16, 0), + rotate( + pivot(0, 0, 0), + angle(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 16 - margin, 16 - alignedLength / 2), + aabb(16, margin, alignedLength / 2).move(0, 16 - margin, marginAdj), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, 16, 16), + scale(1, 1, midLength / alignedLength) + ), + translate(0, 0, -marginAdj - midLength / 2), + rotate( + pivot(16, 16, 16), + angle(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 16 - margin, 16 - alignedLength / 2), + aabb(16, margin, alignedLength / 2).move(0, 16 - margin, 16 - marginAdj - alignedLength / 2), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, 16, 16), + scale(1, 1, midLength / alignedLength) + ), + translate(0, 0, -marginAdj), + rotate( + pivot(16, 16, 16), + angle(-45, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 0, 16 - marginAdj), + aabb(16, 16, marginAdj).move(0, 0, 16 - marginAdj), + cull(DOWN | NORTH | SOUTH), + updateUV(slope(Direction.DOWN, (a, b) -> map(16 - marginAdj, 16, margin, 0, b))), + rotate( + pivot(16, 16, 16), + angle(-45, 0, 0) + ) ); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java new file mode 100644 index 000000000..a301cb3ac --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java @@ -0,0 +1,273 @@ +package com.copycatsplus.copycats.content.copycat.vertical_slope; + +import com.copycatsplus.copycats.CCBlocks; +import com.copycatsplus.copycats.CCShapes; +import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; +import com.copycatsplus.copycats.content.copycat.base.IStateType; +import com.simibubi.create.foundation.placement.IPlacementHelper; +import com.simibubi.create.foundation.placement.PlacementHelpers; +import com.simibubi.create.foundation.placement.PoleHelper; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Pair; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; + +import static net.minecraft.core.Direction.Axis; + +public class CopycatVerticalSlopeBlock extends CTWaterloggedCopycatBlock implements IStateType, ICustomCTBlocking { + + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + + private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); + + public CopycatVerticalSlopeBlock(Properties pProperties) { + super(pProperties); + registerDefaultState(defaultBlockState() + .setValue(FACING, Direction.NORTH)); + } + + @Override + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult ray) { + + if (!player.isShiftKeyDown() && player.mayBuild()) { + ItemStack heldItem = player.getItemInHand(hand); + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem)) { + placementHelper.getOffset(player, world, state, pos, ray) + .placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); + return InteractionResult.SUCCESS; + } + } + + return super.use(state, world, pos, player, hand, ray); + } + + @Override + public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, + BlockPos fromPos, BlockPos toPos) { + Direction direction = state.getValue(FACING); + BlockState toState = reader.getBlockState(toPos); + + BlockPos diff = toPos.subtract(fromPos); + if (diff.equals(Vec3i.ZERO)) { + return false; + } + Direction connectFace = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (connectFace == null) { + return false; + } + + if (toState.is(this)) { + Direction toDirection = toState.getValue(FACING); + if (toDirection == direction) return false; + + if (connectFace == direction.getOpposite() || connectFace == direction.getClockWise()) + return true; + if (connectFace.getOpposite() == toDirection.getOpposite() || connectFace.getOpposite() == toDirection.getClockWise()) + return true; + return false; + } else { + return !(direction == connectFace || direction.getCounterClockWise() == connectFace); + } + } + + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, + BlockState state) { + BlockState toState = reader.getBlockState(toPos); + Direction facing = state.getValue(FACING); + + BlockPos diff = toPos.subtract(fromPos); + if (diff.equals(Vec3i.ZERO)) { + return true; + } + Direction face = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (face == null) { + return true; + } + + if (toState.is(this)) { + try { + return toState.getValue(FACING) == facing && + face.getAxis().isVertical() || + face.getAxis().isHorizontal(); + } catch (IllegalStateException ignored) { + return false; + } + } else { + return face == facing || face == facing.getCounterClockWise(); + } + } + + @Override + public Optional blockCTTowards(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos ctPos, BlockPos connectingPos, Direction face) { + if (reader.getBlockState(ctPos).is(this)) { + return Optional.of(false); + } + return Optional.empty(); + } + + @Override + public Optional isCTBlocked(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos connectingPos, BlockPos blockingPos, Direction face) { + if (reader.getBlockState(blockingPos).is(this)) { + return Optional.of(false); + } + return Optional.empty(); + } + + @SuppressWarnings("deprecation") + @Override + public boolean isPathfindable(@NotNull BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull PathComputationType pType) { + return false; + } + + @Override + public boolean canFaceBeOccluded(BlockState state, Direction face) { + Direction facing = state.getValue(FACING); + return face.getAxis() == Axis.Y || face == facing || face == facing.getCounterClockWise(); + } + + @Override + public boolean shouldFaceAlwaysRender(BlockState state, Direction face) { + return !canFaceBeOccluded(state, face); + } + + private static final Map, Direction> VERTICAL_POSITION_MAP = new HashMap<>(); + private static final Map, Direction> HORIZONTAL_POSITION_MAP = new HashMap<>(); + + static { + for (Direction main : Iterate.horizontalDirections) { + Direction cross = main.getCounterClockWise(); + + int mainOffset = main.getAxisDirection().getStep(); + int crossOffset = cross.getAxisDirection().getStep(); + + if (main.getAxis() == Axis.X) + VERTICAL_POSITION_MAP.put(Pair.of(mainOffset, crossOffset), main); + else + VERTICAL_POSITION_MAP.put(Pair.of(crossOffset, mainOffset), main); + + HORIZONTAL_POSITION_MAP.put(Pair.of(main.getOpposite(), crossOffset), main); + HORIZONTAL_POSITION_MAP.put(Pair.of(cross.getOpposite(), mainOffset), main); + } + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + BlockState stateForPlacement = super.getStateForPlacement(context); + assert stateForPlacement != null; + + int xOffset = context.getClickLocation().x - context.getClickedPos().getX() > 0.5 ? 1 : -1; + int zOffset = context.getClickLocation().z - context.getClickedPos().getZ() > 0.5 ? 1 : -1; + + if (context.getClickedFace().getAxis() == Axis.Y) { + return stateForPlacement.setValue(FACING, VERTICAL_POSITION_MAP.get(Pair.of(xOffset, zOffset))); + } else { + return stateForPlacement.setValue(FACING, HORIZONTAL_POSITION_MAP.get( + Pair.of(context.getClickedFace(), context.getClickedFace().getAxis() == Axis.X ? zOffset : xOffset) + )); + } + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + super.createBlockStateDefinition(pBuilder.add(FACING)); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull VoxelShape getShape(BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull CollisionContext pContext) { + return CCShapes.SLOPE_LEFT.get(pState.getValue(FACING)); + } + + + public boolean supportsExternalFaceHiding(BlockState state) { + return true; + } + + + public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, + Direction dir) { + if (state.is(this) == neighborState.is(this)) { + if (getMaterial(level, pos).skipRendering(getMaterial(level, pos.relative(dir)), dir.getOpposite())) { + return dir.getAxis().isVertical() && neighborState.getValue(FACING) == state.getValue(FACING); + } + } + + return false; + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState rotate(@NotNull BlockState pState, Rotation pRot) { + return pState.setValue(FACING, pRot.rotate(pState.getValue(FACING))); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState mirror(@NotNull BlockState pState, @NotNull Mirror pMirror) { + Axis mirrorAxis = null; + for (Axis axis : Iterate.axes) { + if (pMirror.rotation().inverts(axis)) { + mirrorAxis = axis; + break; + } + } + if (mirrorAxis == null || mirrorAxis.isVertical()) { + return super.mirror(pState, pMirror); + } + Direction facing = pState.getValue(FACING); + if (facing.getAxis() != mirrorAxis) { + return pState.setValue(FACING, facing.getClockWise()); + } else { + return pState.setValue(FACING, facing.getCounterClockWise()); + } + } + + @MethodsReturnNonnullByDefault + private static class PlacementHelper extends PoleHelper { + + private PlacementHelper() { + super(CCBlocks.COPYCAT_VERTICAL_STEP::has, $ -> Axis.Y, FACING); + } + + @Override + public Predicate getItemPredicate() { + return i -> i.getItem() instanceof BlockItem + && (((BlockItem) i.getItem()).getBlock() instanceof CopycatVerticalSlopeBlock); + } + + } + +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java new file mode 100644 index 000000000..0cc359ce2 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java @@ -0,0 +1,37 @@ +package com.copycatsplus.copycats.content.copycat.vertical_slope; + +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeBlock; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; +import com.simibubi.create.foundation.utility.Iterate; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import static com.copycatsplus.copycats.content.copycat.base.model.PlatformModelUtils.assembleVerticalStep; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; + +public class CopycatVerticalSlopeModel implements SimpleCopycatPart { + + private final boolean enhanced; + + public CopycatVerticalSlopeModel(boolean enhanced) { + this.enhanced = enhanced; + } + + @Override + public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { + Direction facing = state.getValue(CopycatVerticalSlopeBlock.FACING); + int rot = (int) facing.toYRot(); + GlobalTransform transform = t -> t.rotateZ(-90).rotateY(rot); + if (enhanced) + CopycatSlopeModel.assembleSlope(context, transform, 16, 0, 3); + else + CopycatSlopeModel.assembleSlope(context, transform, 16, 0); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java index c425a71e0..8df7f824b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java @@ -171,6 +171,8 @@ public class CCStandardRecipes extends CopycatsRecipeProvider { GeneratedRecipe COPYCAT_SLOPE = copycat(CCBlocks.COPYCAT_SLOPE, 2); + GeneratedRecipe COPYCAT_VERTICAL_SLOPE = copycat(CCBlocks.COPYCAT_VERTICAL_SLOPE, 2); + String currentFolder = ""; diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/vertical_slope.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/vertical_slope.json new file mode 100644 index 000000000..dbcefcdce --- /dev/null +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/vertical_slope.json @@ -0,0 +1,38 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "copycats:block/copycat_slope", + "2": "create:block/copycat_base", + "particle": "create:block/copycat_base" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "south": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#2"}, + "west": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#2"}, + "up": {"uv": [16, 0, 0, 16], "texture": "#1"}, + "down": {"uv": [0, 0, 16, 16], "rotation": 180, "texture": "#1"} + } + }, + { + "from": [4.6863, 0, 16], + "to": [16, 16, 16], + "rotation": {"angle": -45, "axis": "y", "origin": [16, 8, 16]}, + "faces": { + "north": {"uv": [0, 5, 16, 16], "rotation": 90, "texture": "#2"} + } + }, + { + "from": [-3.3137, 0, 8], + "to": [8, 16, 8], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 11], "rotation": 90, "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json index b15de372a..f3484e0d4 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json @@ -125,6 +125,7 @@ "block.copycats.copycat_vertical_slice.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_vertical_slope": "ǝdoןS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs": "sɹıɐʇS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_us.json b/fabric/src/generated/resources/assets/copycats/lang/en_us.json index 297e3a7a3..22dcf343b 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_us.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_us.json @@ -125,6 +125,7 @@ "block.copycats.copycat_vertical_slice.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", "block.copycats.copycat_vertical_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_vertical_slice.tooltip.summary": "_Converts_ any _full block_ into decorative vertical slices. Slices can be enlarged till it reaches a full block in size.", + "block.copycats.copycat_vertical_slope": "Copycat Vertical Slope", "block.copycats.copycat_vertical_stairs": "Copycat Vertical Stairs", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/fabric/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json b/fabric/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json new file mode 100644 index 000000000..7e4a96147 --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/vertical_slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json new file mode 100644 index 000000000..9a5081760 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "c:zinc_ingots" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_vertical_slope" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_vertical_slope" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json new file mode 100644 index 000000000..3d89dace6 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_vertical_slope" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_vertical_slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json new file mode 100644 index 000000000..2045a56ac --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "c:zinc_ingots" + }, + "result": "copycats:copycat_vertical_slope" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 69cd8d562..32634e6d8 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_vertical_slope" ] } \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 69cd8d562..32634e6d8 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_vertical_slope" ] } \ No newline at end of file diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java index 3ad81c798..a6f83f400 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/fabric/AssemblerImpl.java @@ -86,6 +86,7 @@ public static BakedQuadHelper.setXYZ(dest, i, mutableQuad.vertices.get(i).xyz.toVec3()); dest.uv(i, mutableQuad.vertices.get(i).uv.u, mutableQuad.vertices.get(i).uv.v); } + // todo: assign lightFace dest.emit(); } @@ -97,7 +98,7 @@ public static MutableQuad getMutableQuad(T data) { MutableUV uv = new MutableUV(vertexData.u(i), vertexData.v(i)); vertices.add(new MutableVertex(xyz, uv)); } - return new MutableQuad(vertices); + return new MutableQuad(vertices, vertexData.lightFace()); } public static class CopycatRenderContextFabric extends CopycatRenderContext { diff --git a/forge/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json b/forge/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/blockstates/copycat_vertical_slope.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/lang/en_ud.json b/forge/src/generated/resources/assets/copycats/lang/en_ud.json index b15de372a..f3484e0d4 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_ud.json @@ -125,6 +125,7 @@ "block.copycats.copycat_vertical_slice.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_vertical_slope": "ǝdoןS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs": "sɹıɐʇS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/forge/src/generated/resources/assets/copycats/lang/en_us.json b/forge/src/generated/resources/assets/copycats/lang/en_us.json index 297e3a7a3..22dcf343b 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_us.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_us.json @@ -125,6 +125,7 @@ "block.copycats.copycat_vertical_slice.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", "block.copycats.copycat_vertical_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_vertical_slice.tooltip.summary": "_Converts_ any _full block_ into decorative vertical slices. Slices can be enlarged till it reaches a full block in size.", + "block.copycats.copycat_vertical_slope": "Copycat Vertical Slope", "block.copycats.copycat_vertical_stairs": "Copycat Vertical Stairs", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/forge/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json b/forge/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json new file mode 100644 index 000000000..7e4a96147 --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/models/item/copycat_vertical_slope.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/vertical_slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json new file mode 100644 index 000000000..6da1c5e72 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_vertical_slope.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "forge:ingots/zinc" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_vertical_slope" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_vertical_slope" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json new file mode 100644 index 000000000..3d89dace6 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_vertical_slope.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_vertical_slope" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_vertical_slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json new file mode 100644 index 000000000..c5eb80d65 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_vertical_slope.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "forge:ingots/zinc" + }, + "result": "copycats:copycat_vertical_slope" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 98ded5df5..da749ddc4 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -25,6 +25,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_vertical_slope" ] } \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 98ded5df5..da749ddc4 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -25,6 +25,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_vertical_slope" ] } \ No newline at end of file diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java index 37a3ced40..3ec79ac7a 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/assembly/forge/AssemblerImpl.java @@ -78,7 +78,7 @@ public static > vo public static > void assembleQuad(Source src, Destination dest, AABB crop, Vec3 move, GlobalTransform globalTransform, QuadTransform... transforms) { int[] vertices = BakedModelHelper.cropAndMove(src.getVertices(), src.getSprite(), crop, move); - MutableQuad mutableQuad = getMutableQuad(vertices); + MutableQuad mutableQuad = getMutableQuad(new BakedQuad(vertices, src.getTintIndex(), src.getDirection(), src.getSprite(), src.isShade())); globalTransform.apply(mutableQuad); mutableQuad.undoMutate(); for (QuadTransform transform : transforms) { @@ -90,18 +90,19 @@ public static > vo BakedQuadHelper.setU(vertices, i, mutableQuad.vertices.get(i).uv.u); BakedQuadHelper.setV(vertices, i, mutableQuad.vertices.get(i).uv.v); } - dest.add(BakedQuadHelper.cloneWithCustomGeometry(src, vertices)); + dest.add(new BakedQuad(vertices, src.getTintIndex(), mutableQuad.direction, src.getSprite(), src.isShade())); } public static MutableQuad getMutableQuad(T data) { - int[] vertexData = (int[]) data; + BakedQuad quad = (BakedQuad) data; + int[] vertexData = quad.getVertices(); List vertices = new ArrayList<>(4); for (int i = 0; i < 4; i++) { MutableVec3 xyz = new MutableVec3(BakedQuadHelper.getXYZ(vertexData, i)); MutableUV uv = new MutableUV(BakedQuadHelper.getU(vertexData, i), BakedQuadHelper.getV(vertexData, i)); vertices.add(new MutableVertex(xyz, uv)); } - return new MutableQuad(vertices); + return new MutableQuad(vertices, quad.getDirection()); } public static class CopycatRenderContextForge extends CopycatRenderContext, List> { From 0ebd1c5e0c46fd152acad212012895670ac9f4c6 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 22:30:42 +0800 Subject: [PATCH 23/71] Modify CT toggle logic to work on both fabric and forge --- .../copycats/content/copycat/base/ICTCopycatBlock.java | 6 ++---- .../mixin/copycat/base/CopycatBlockEntityMixin.java | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java index 1632df310..c5ba39afe 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/ICTCopycatBlock.java @@ -19,11 +19,9 @@ public interface ICTCopycatBlock extends IBE { default boolean allowCTAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, BlockState queryState, BlockPos queryPos) { - CopycatBlockEntity be = getBlockEntity(level, pos); + CopycatBlockEntity be = getBlockEntity(level, queryPos); if (be instanceof CTCopycatBlockEntity ctbe) { - if (!ctbe.isCTEnabled()) { - return queryState.getBlock() instanceof ICTCopycatBlock; - } + return ctbe.isCTEnabled(); } return true; } diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityMixin.java index 6ce78a4d2..7dce43401 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityMixin.java @@ -39,7 +39,7 @@ public boolean isCTEnabled() { @Override public void setCTEnabled(boolean value) { enableCT = value; - setChanged(); + notifyUpdate(); } @Inject( From 477ef42633291fe9b17839a4927c6aa006de264c Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 23:14:12 +0800 Subject: [PATCH 24/71] Implement CT toggle for multistates, todo: fix toggle for slabs --- .../copycats/CCBlockEntityTypes.java | 4 -- .../CTWaterloggedMultiStateCopycatBlock.java | 32 --------------- .../multistate/ICTMultiStateCopycatBlock.java | 40 ------------------- .../base/multistate/MaterialItemStorage.java | 37 +++++++++++++---- .../multistate/MultiStateCopycatBlock.java | 26 ++++++++++++ .../MultiStateCopycatBlockEntity.java | 6 ++- .../copycat/board/CopycatBoardBlock.java | 5 +-- .../copycat/bytes/CopycatByteBlock.java | 4 +- .../half_layer/CopycatHalfLayerBlock.java | 4 +- .../copycat/slab/CopycatSlabBlock.java | 4 +- .../fabric/MultiStateCopycatModel.java | 4 +- .../fabric/MultiStateCopycatBlockImpl.java | 2 + .../mixin/copycat/base/CopycatModelMixin.java | 36 ----------------- .../resources/copycats-fabric.mixins.json | 1 - .../forge/MultiStateCopycatBlockImpl.java | 2 + 15 files changed, 74 insertions(+), 133 deletions(-) delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/CTWaterloggedMultiStateCopycatBlock.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java index b35743d8a..81b6c5e1b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java @@ -14,7 +14,6 @@ public class CCBlockEntityTypes { REGISTRATE.blockEntity("copycat", CopycatBlockEntity::new) .validBlocks( CCBlocks.COPYCAT_BLOCK, - /* CCBlocks.COPYCAT_SLAB,*/ CCBlocks.COPYCAT_BEAM, CCBlocks.COPYCAT_VERTICAL_STEP, CCBlocks.COPYCAT_HALF_PANEL, @@ -23,12 +22,9 @@ public class CCBlockEntityTypes { CCBlocks.COPYCAT_FENCE_GATE, CCBlocks.COPYCAT_TRAPDOOR, CCBlocks.COPYCAT_WALL, -/* CCBlocks.COPYCAT_BOARD,*/ - /* CCBlocks.COPYCAT_BYTE,*/ CCBlocks.COPYCAT_GHOST_BLOCK, CCBlocks.COPYCAT_LADDER, CCBlocks.COPYCAT_LAYER, -/* CCBlocks.COPYCAT_HALF_LAYER,*/ CCBlocks.COPYCAT_SLICE, CCBlocks.COPYCAT_VERTICAL_SLICE, CCBlocks.COPYCAT_WOODEN_BUTTON, diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/CTWaterloggedMultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/CTWaterloggedMultiStateCopycatBlock.java deleted file mode 100644 index 17dc6ef9d..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/CTWaterloggedMultiStateCopycatBlock.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.multistate; - -import com.copycatsplus.copycats.content.copycat.base.ICTCopycatBlock; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; - -public abstract class CTWaterloggedMultiStateCopycatBlock extends WaterloggedMultiStateCopycatBlock implements ICTMultiStateCopycatBlock { - public CTWaterloggedMultiStateCopycatBlock(Properties properties) { - super(properties); - } - -/* @Override - public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, BlockState queryState, BlockPos queryPos) { - if (!allowCTAppearance(state, level, pos, side, queryState, queryPos)) - return state; - return super.getAppearance(state, level, pos, side, queryState, queryPos); - }*/ - - @Override - public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) { - InteractionResult toggleResult = ICTMultiStateCopycatBlock.super.toggleCT(pState, pLevel, pPos, pPlayer, pHand, pHit); - if (toggleResult.consumesAction()) return toggleResult; - return super.use(pState, pLevel, pPos, pPlayer, pHand, pHit); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java deleted file mode 100644 index c9f5b5e96..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/ICTMultiStateCopycatBlock.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.multistate; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.copycatsplus.copycats.content.copycat.base.ICTCopycatBlock; -import com.simibubi.create.foundation.block.IBE; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; - -public interface ICTMultiStateCopycatBlock extends IBE { - - default boolean allowCTAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, BlockState queryState, BlockPos queryPos) { - MultiStateCopycatBlockEntity be = getBlockEntity(level, pos); - if (be instanceof CTCopycatBlockEntity ctbe) { - if (!ctbe.isCTEnabled()) { - return queryState.getBlock() instanceof ICTCopycatBlock; - } - } - return true; - } - - default InteractionResult toggleCT(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) { - if (pPlayer.isShiftKeyDown() && pPlayer.getItemInHand(pHand).equals(ItemStack.EMPTY)) { - MultiStateCopycatBlockEntity be = getBlockEntity(pLevel, pPos); - if (be instanceof CTCopycatBlockEntity ctbe) { - ctbe.setCTEnabled(!ctbe.isCTEnabled()); - ctbe.callRedraw(); - return InteractionResult.SUCCESS; - } - } - return InteractionResult.PASS; - } -} \ No newline at end of file diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java index a6cedf7d0..aa4904b59 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MaterialItemStorage.java @@ -85,10 +85,12 @@ public boolean deserialize(CompoundTag tag) { AtomicBoolean anyUpdated = new AtomicBoolean(false); tag.getAllKeys().forEach(key -> { MaterialItem newVersion = MaterialItem.deserialize(tag.getCompound(key)); - if (newVersion.material() != storage.put(key, newVersion).material() && !anyUpdated.get()) { + MaterialItem oldVersion = storage.put(key, newVersion); + if (oldVersion != null && + (newVersion.material() != oldVersion.material() || newVersion.enableCT() != oldVersion.enableCT()) && + !anyUpdated.get()) { anyUpdated.set(true); } - ; }); return anyUpdated.get(); } @@ -99,20 +101,23 @@ public static class MaterialItem { private BlockState material; private ItemStack consumedItem; + private boolean enableCT; public MaterialItem(BlockState material, ItemStack consumedItem) { - this.material = material; - this.consumedItem = consumedItem; + this(material, consumedItem, true); } - public void setConsumedItem(ItemStack stack) { - consumedItem = ItemUtils.copyStackWithSize(stack, 1); + public MaterialItem(BlockState material, ItemStack consumedItem, boolean enableCT) { + this.material = material; + this.consumedItem = consumedItem; + this.enableCT = enableCT; } public CompoundTag serialize() { CompoundTag root = new CompoundTag(); root.put("material", NbtUtils.writeBlockState(material)); root.put("consumedItem", NBTUtils.serializeStack(consumedItem)); + root.putBoolean("enableCT", enableCT); return root; } @@ -122,12 +127,16 @@ public CompoundTag serializeSafe() { ItemStack stackEmpty = consumedItem.copy(); stackEmpty.setTag(null); root.put("consumedItem", NBTUtils.serializeStack(stackEmpty)); + root.putBoolean("enableCT", enableCT); return root; } public static MaterialItem deserialize(CompoundTag tag) { - return new MaterialItem(NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("material")), - ItemStack.of(tag.getCompound("consumedItem"))); + return new MaterialItem( + NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("material")), + ItemStack.of(tag.getCompound("consumedItem")), + !tag.contains("enableCT") || tag.getBoolean("enableCT") + ); } public BlockState material() { @@ -138,9 +147,21 @@ public ItemStack consumedItem() { return consumedItem; } + public boolean enableCT() { + return enableCT; + } + public void setMaterial(BlockState material) { this.material = material; } + + public void setConsumedItem(ItemStack stack) { + consumedItem = ItemUtils.copyStackWithSize(stack, 1); + } + + public void setEnableCT(boolean enableCT) { + this.enableCT = enableCT; + } } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java index b16aba27e..299f5cb08 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java @@ -2,11 +2,13 @@ import com.copycatsplus.copycats.CCBlockEntityTypes; import com.copycatsplus.copycats.CCBlockStateProperties; +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.IStateType; import com.copycatsplus.copycats.content.copycat.base.StateType; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; import com.simibubi.create.content.equipment.wrench.IWrenchable; import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.requirement.ItemRequirement; @@ -154,8 +156,17 @@ public InteractionResult onWrenched(BlockState state, UseOnContext context) { }); } + @SuppressWarnings("deprecation") @Override public @NotNull InteractionResult use(@NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hit) { + if (player.isShiftKeyDown() && player.getItemInHand(hand).equals(ItemStack.EMPTY)) { + String property = getProperty(state, level, pos, hit, true); + MultiStateCopycatBlockEntity be = getBlockEntity(level, pos); + be.setEnableCT(property, !be.getMaterialItemStorage().getMaterialItem(property).enableCT()); + be.redraw(); + return InteractionResult.SUCCESS; + } + if (player == null || !player.mayBuild() && !player.isSpectator()) return InteractionResult.PASS; @@ -336,6 +347,21 @@ public BlockState getAppearance(BlockState state, BlockAndTintGetter level, Bloc return multiPlatformGetAppearance(this, state, level, pos, side, queryState, queryPos); } + public boolean allowCTAppearance(MultiStateCopycatBlock block, BlockState state, BlockAndTintGetter level, Direction side, + BlockState queryState, BlockPos queryPos) { + String property; + if (level instanceof ScaledBlockAndTintGetter scaledLevel) { + BlockPos truePos = scaledLevel.getTruePos(queryPos); + Vec3i inner = scaledLevel.getInner(queryPos); + property = block.getPropertyFromRender(scaledLevel.getRenderingProperty(), state, scaledLevel, inner, truePos, side, queryState, queryPos); + } else { + property = block.storageProperties().stream().findFirst().get(); + } + MultiStateCopycatBlockEntity be = getBlockEntity(level, queryPos); + if (be == null) return true; + return be.getMaterialItemStorage().getMaterialItem(property).enableCT(); + } + public boolean isIgnoredConnectivitySide(String property, BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { BlockState toState = reader.getBlockState(toPos); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java index 1ebea5156..0a9fd872e 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java @@ -121,10 +121,14 @@ public void setMaterial(String property, BlockState blockState) { public void setConsumedItem(String property, ItemStack itemStack) { getMaterialItemStorage().getMaterialItem(property).setConsumedItem(itemStack); setChanged(); + } + public void setEnableCT(String property, boolean value) { + getMaterialItemStorage().getMaterialItem(property).setEnableCT(value); + notifyUpdate(); } - private void redraw() { + public void redraw() { if (!isVirtual()) requestModelUpdate(); if (hasLevel()) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java index 69cd3611c..ec9376f14 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/board/CopycatBoardBlock.java @@ -2,10 +2,9 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; -import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; -import com.copycatsplus.copycats.content.copycat.base.multistate.MaterialItemStorage; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; +import com.copycatsplus.copycats.content.copycat.base.multistate.WaterloggedMultiStateCopycatBlock; import com.google.common.collect.ImmutableMap; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Iterate; @@ -43,7 +42,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -public class CopycatBoardBlock extends CTWaterloggedMultiStateCopycatBlock implements ICustomCTBlocking { +public class CopycatBoardBlock extends WaterloggedMultiStateCopycatBlock implements ICustomCTBlocking { public static BooleanProperty UP = BlockStateProperties.UP; public static BooleanProperty DOWN = BlockStateProperties.DOWN; public static BooleanProperty NORTH = BlockStateProperties.NORTH; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java index 45f0a9b6c..ee01a4ffc 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/bytes/CopycatByteBlock.java @@ -1,8 +1,8 @@ package com.copycatsplus.copycats.content.copycat.bytes; import com.copycatsplus.copycats.Copycats; -import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.multistate.WaterloggedMultiStateCopycatBlock; import com.google.common.collect.ImmutableMap; import com.mojang.math.OctahedralGroup; import com.simibubi.create.AllBlocks; @@ -37,7 +37,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -public class CopycatByteBlock extends CTWaterloggedMultiStateCopycatBlock { +public class CopycatByteBlock extends WaterloggedMultiStateCopycatBlock { public static BooleanProperty TOP_NE = BooleanProperty.create("top_northeast"); public static BooleanProperty TOP_NW = BooleanProperty.create("top_northwest"); public static BooleanProperty TOP_SE = BooleanProperty.create("top_southeast"); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java index ee584200e..753c1c41b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java @@ -2,9 +2,9 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.Copycats; -import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; +import com.copycatsplus.copycats.content.copycat.base.multistate.WaterloggedMultiStateCopycatBlock; import com.google.common.collect.ImmutableMap; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.VoxelShaper; @@ -44,7 +44,7 @@ import static net.minecraft.core.Direction.Axis; import static net.minecraft.core.Direction.AxisDirection; -public class CopycatHalfLayerBlock extends CTWaterloggedMultiStateCopycatBlock { +public class CopycatHalfLayerBlock extends WaterloggedMultiStateCopycatBlock { public static final EnumProperty AXIS = BlockStateProperties.HORIZONTAL_AXIS; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java index c6528d755..7062ef06d 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java @@ -3,9 +3,9 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.ICopycatWithWrappedBlock; -import com.copycatsplus.copycats.content.copycat.base.multistate.CTWaterloggedMultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; +import com.copycatsplus.copycats.content.copycat.base.multistate.WaterloggedMultiStateCopycatBlock; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.decoration.copycat.CopycatBlock; import com.simibubi.create.foundation.placement.IPlacementHelper; @@ -47,7 +47,7 @@ import java.util.Set; import java.util.function.Predicate; -public class CopycatSlabBlock extends CTWaterloggedMultiStateCopycatBlock implements ICopycatWithWrappedBlock { +public class CopycatSlabBlock extends WaterloggedMultiStateCopycatBlock implements ICopycatWithWrappedBlock { public static final EnumProperty AXIS = BlockStateProperties.AXIS; public static final EnumProperty SLAB_TYPE = BlockStateProperties.SLAB_TYPE; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java index ea1c85c24..2a709c7b5 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java @@ -77,7 +77,7 @@ public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, Block materials = new HashMap<>((Map) mats); } } else { - materials = Map.of(); + materials = new HashMap<>(); } if (materials.isEmpty()) { if (state.getBlock() instanceof MultiStateCopycatBlock copycatBlock) { @@ -127,7 +127,7 @@ public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, Block @Override public @NotNull TextureAtlasSprite getParticleIcon(Object data) { - if (data instanceof Map mats) { + if (data instanceof Map mats) { if (mats.isEmpty()) return super.getParticleIcon(); Map.Entry key = (Map.Entry) mats.entrySet().stream().findFirst().get(); diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java index 2b960439d..1f8dd73ba 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/fabric/MultiStateCopycatBlockImpl.java @@ -84,6 +84,8 @@ public static BlockState multiPlatformGetAppearance(MultiStateCopycatBlock block } else { property = block.storageProperties().stream().findFirst().get(); } + if (!block.allowCTAppearance(block, state, level, side, queryState, queryPos)) + return state; if (block.isIgnoredConnectivitySide(property, level, state, side, pos, queryPos)) return state; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java deleted file mode 100644 index 2bcd27f2d..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.copycatsplus.copycats.fabric.mixin.copycat.base; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.function.Supplier; - -@Mixin(value = CopycatModel.class, remap = false) -public class CopycatModelMixin { - - /* //Toggles Rendering 😂 - @Inject( - at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/decoration/copycat/CopycatModel;gatherOcclusionData(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$OcclusionData;Lcom/simibubi/create/content/decoration/copycat/CopycatBlock;)V", shift = At.Shift.BEFORE), - method = "emitBlockQuads", - cancellable = true - ) - - private void considerCT(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, CallbackInfo ci) { - BlockEntity be = blockView.getBlockEntity(pos); - if (!(be instanceof CTCopycatBlockEntity ctbe)) return; - if (!ctbe.isCTEnabled()) ci.cancel(); - }*/ -} diff --git a/fabric/src/main/resources/copycats-fabric.mixins.json b/fabric/src/main/resources/copycats-fabric.mixins.json index 95c1bdc32..a3238e76d 100644 --- a/fabric/src/main/resources/copycats-fabric.mixins.json +++ b/fabric/src/main/resources/copycats-fabric.mixins.json @@ -7,7 +7,6 @@ "mixins": [ "HolderReferenceInvoker", "compat.registrate.CreateRegistrateMixin", - "copycat.base.CopycatModelMixin", "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin" ], "client": [ diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java index 381263e72..2d3c04a6b 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/forge/MultiStateCopycatBlockImpl.java @@ -40,6 +40,8 @@ public static BlockState multiPlatformGetAppearance(MultiStateCopycatBlock block } else { property = block.storageProperties().stream().findFirst().get(); } + if (!block.allowCTAppearance(block, state, level, side, queryState, queryPos)) + return state; if (block.isIgnoredConnectivitySide(property, level, state, side, pos, queryPos)) return state; From 9b9d020521c3ff7b4ef69ee52b7a991758e6f161 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sat, 22 Jun 2024 23:30:44 +0800 Subject: [PATCH 25/71] Fix incorrect face culling in half layers --- .../content/copycat/half_layer/CopycatHalfLayerBlock.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java index 753c1c41b..415557793 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/half_layer/CopycatHalfLayerBlock.java @@ -350,6 +350,14 @@ public boolean shouldFaceAlwaysRender(BlockState state, Direction face) { if (face.getAxis().isVertical() && (state.getValue(HALF) == Half.TOP) == (face == Direction.DOWN)) { return state.getValue(POSITIVE_LAYERS) < 8 || state.getValue(NEGATIVE_LAYERS) < 8; } + if (face.getAxis() == state.getValue(AXIS)) { + int negativeLayers = state.getValue(NEGATIVE_LAYERS); + int positiveLayers = state.getValue(POSITIVE_LAYERS); + if (face.getAxisDirection() == AxisDirection.NEGATIVE && negativeLayers < positiveLayers) + return true; + if (face.getAxisDirection() == AxisDirection.POSITIVE && positiveLayers < negativeLayers) + return true; + } return super.shouldFaceAlwaysRender(state, face); } From a8a3c720fce28c9f227a937dbc4729edc2f84b09 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 09:28:20 +0800 Subject: [PATCH 26/71] Rework slabs to use assembly API --- .../base/model/PlatformModelUtils.java | 7 --- .../copycat/slab/CopycatMultiSlabModel.java | 58 +++++++++-------- .../copycat/slab/CopycatSlabModel.java | 63 +++++++++++-------- .../test_block/CopycatTestBlockModel.java | 41 +----------- .../model/fabric/PlatformModelUtilsImpl.java | 18 ------ .../model/forge/PlatformModelUtilsImpl.java | 20 ------ 6 files changed, 74 insertions(+), 133 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/PlatformModelUtils.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/PlatformModelUtils.java index d7e094f95..dd8f1b996 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/PlatformModelUtils.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/PlatformModelUtils.java @@ -1,8 +1,6 @@ package com.copycatsplus.copycats.content.copycat.base.model; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler; import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; @@ -11,11 +9,6 @@ public class PlatformModelUtils { - @ExpectPlatform - public static void cullFacing(Direction facing, Assembler.CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble, AABB bb, Vec3 normalScaledN8) { - - } - @ExpectPlatform public static void quadShift(CopycatRenderContext context, Vec3i rowShiftNormal, Vec3i columnShiftNormal, AABB bb1, Vec3 offset) { diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatMultiSlabModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatMultiSlabModel.java index 0369f46c3..4120e76a2 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatMultiSlabModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatMultiSlabModel.java @@ -1,25 +1,21 @@ package com.copycatsplus.copycats.content.copycat.slab; import com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; import com.copycatsplus.copycats.content.copycat.base.model.multistate.SimpleMultiStateCopycatPart; -import com.simibubi.create.foundation.utility.Iterate; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.SlabType; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; import java.util.Objects; -import static com.copycatsplus.copycats.content.copycat.base.model.PlatformModelUtils.cullFacing; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; import static net.minecraft.core.Direction.Axis; import static net.minecraft.core.Direction.AxisDirection; public class CopycatMultiSlabModel implements SimpleMultiStateCopycatPart { - static final AABB CUBE_AABB = new AABB(BlockPos.ZERO); - @Override public void emitCopycatQuads(String key, BlockState state, CopycatRenderContext context, BlockState material) { if (Objects.equals(key, SlabType.TOP.getSerializedName()) && state.getValue(CopycatSlabBlock.SLAB_TYPE) == SlabType.BOTTOM) @@ -28,24 +24,36 @@ public void emitCopycatQuads(String key, BlockState state, CopycatRenderContext< return; Axis axis = state.getValue(CopycatSlabBlock.AXIS); - Direction facing = Direction.fromAxisAndDirection(axis, Objects.equals(key, SlabType.BOTTOM.getSerializedName()) ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); - - // 2 pieces - for (boolean front : Iterate.trueAndFalse) { - assemblePiece(facing, context, front, false, false); + Direction facing = Direction.fromAxisAndDirection(axis, Objects.equals(key, SlabType.BOTTOM.getSerializedName()) ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE); + + if (facing.getAxis().isHorizontal()) { + GlobalTransform transform = t -> t.rotateY((int) facing.toYRot()); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, 4), + cull(SOUTH) + ); + assemblePiece(context, + transform, + vec3(0, 0, 4), + aabb(16, 16, 4).move(0, 0, 12), + cull(NORTH) + ); + } else { + GlobalTransform transform = t -> t.flipY(facing.getAxisDirection() == AxisDirection.NEGATIVE); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 4, 16), + cull(UP) + ); + assemblePiece(context, + transform, + vec3(0, 4, 0), + aabb(16, 4, 16).move(0, 12, 0), + cull(DOWN) + ); } } - - private void assemblePiece(Direction facing, CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble) { - Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal()); - Vec3 normalScaled12 = normal.scale(12 / 16f); - Vec3 normalScaledN8 = topSlab ? normal.scale((front ? 0 : -8) / 16f) : normal.scale((front ? 8 : 0) / 16f); - float contract = 12; - AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16); - if (!front) - bb = bb.move(normalScaled12); - - //Not sure on the name. But i needed to extract this to make it platform-agnostic - cullFacing(facing, context, front, topSlab, isDouble, bb, normalScaledN8); - } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabModel.java index 99565df37..b3639aaa6 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabModel.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.slab; import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -9,41 +10,53 @@ import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import java.util.Objects; + import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; -import static com.copycatsplus.copycats.content.copycat.base.model.PlatformModelUtils.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.DOWN; public class CopycatSlabModel implements SimpleCopycatPart { - static final AABB CUBE_AABB = new AABB(BlockPos.ZERO); - @Override public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { Direction facing = state.getOptionalValue(CopycatSlabBlock.SLAB_TYPE).isPresent() ? CopycatSlabBlock.getApparentDirection(state) : Direction.UP; boolean isDouble = state.getOptionalValue(CopycatSlabBlock.SLAB_TYPE).orElse(SlabType.BOTTOM) == SlabType.DOUBLE; - // 2 pieces - for (boolean front : Iterate.trueAndFalse) { - assemblePiece(facing, context, front, false, isDouble); - } - - // 2 more pieces for double slabs - if (isDouble) { - for (boolean front : Iterate.trueAndFalse) { - assemblePiece(facing, context, front, true, isDouble); - } - } + assembleSlab(context, facing); + if (isDouble) + assembleSlab(context, facing.getOpposite()); } - private void assemblePiece(Direction facing, CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble) { - Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal()); - Vec3 normalScaled12 = normal.scale(12 / 16f); - Vec3 normalScaledN8 = topSlab ? normal.scale((front ? 0 : -8) / 16f) : normal.scale((front ? 8 : 0) / 16f); - float contract = 12; - AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16); - if (!front) - bb = bb.move(normalScaled12); - - //Not sure on the name. But i needed to extract this to make it platform-agnostic - cullFacing(facing, context, front, topSlab, isDouble, bb, normalScaledN8); + private static void assembleSlab(CopycatRenderContext context, Direction facing) { + if (facing.getAxis().isHorizontal()) { + GlobalTransform transform = t -> t.rotateY((int) facing.toYRot()); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, 4), + cull(SOUTH) + ); + assemblePiece(context, + transform, + vec3(0, 0, 4), + aabb(16, 16, 4).move(0, 0, 12), + cull(NORTH) + ); + } else { + GlobalTransform transform = t -> t.flipY(facing.getAxisDirection() == Direction.AxisDirection.NEGATIVE); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 4, 16), + cull(UP) + ); + assemblePiece(context, + transform, + vec3(0, 4, 0), + aabb(16, 4, 16).move(0, 12, 0), + cull(DOWN) + ); + } } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlockModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlockModel.java index 4fcece5ee..93259b8f8 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlockModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/test_block/CopycatTestBlockModel.java @@ -2,50 +2,15 @@ import com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; import com.copycatsplus.copycats.content.copycat.base.model.multistate.SimpleMultiStateCopycatPart; -import com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock; -import com.simibubi.create.foundation.utility.Iterate; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; +import com.copycatsplus.copycats.content.copycat.slab.CopycatMultiSlabModel; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.SlabType; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; - -import java.util.Objects; - -import static com.copycatsplus.copycats.content.copycat.base.model.PlatformModelUtils.cullFacing; -import static net.minecraft.core.Direction.*; public class CopycatTestBlockModel implements SimpleMultiStateCopycatPart { - static final AABB CUBE_AABB = new AABB(BlockPos.ZERO); + private final CopycatMultiSlabModel model = new CopycatMultiSlabModel(); @Override public void emitCopycatQuads(String key, BlockState state, CopycatRenderContext context, BlockState material) { - if (Objects.equals(key, SlabType.TOP.getSerializedName()) && state.getValue(CopycatSlabBlock.SLAB_TYPE) == SlabType.BOTTOM) - return; - if (Objects.equals(key, SlabType.BOTTOM.getSerializedName()) && state.getValue(CopycatSlabBlock.SLAB_TYPE) == SlabType.TOP) - return; - - Axis axis = state.getValue(CopycatSlabBlock.AXIS); - Direction facing = Direction.fromAxisAndDirection(axis, Objects.equals(key, SlabType.BOTTOM.getSerializedName()) ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); - - // 2 pieces - for (boolean front : Iterate.trueAndFalse) { - assemblePiece(facing, context, front, false, false); - } - } - - private void assemblePiece(Direction facing, CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble) { - Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal()); - Vec3 normalScaled12 = normal.scale(12 / 16f); - Vec3 normalScaledN8 = topSlab ? normal.scale((front ? 0 : -8) / 16f) : normal.scale((front ? 8 : 0) / 16f); - float contract = 12; - AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16); - if (!front) - bb = bb.move(normalScaled12); - - //Not sure on the name. But i needed to extract this to make it platform-agnostic - cullFacing(facing, context, front, topSlab, isDouble, bb, normalScaledN8); + model.emitCopycatQuads(key, state, context, material); } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/PlatformModelUtilsImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/PlatformModelUtilsImpl.java index 5ae254e44..5edc95a0e 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/PlatformModelUtilsImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/PlatformModelUtilsImpl.java @@ -13,24 +13,6 @@ public class PlatformModelUtilsImpl { - //Used in Slabs - public static void cullFacing(Direction facing, CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble, AABB bb, Vec3 normalScaledN8) { - - Direction direction = context.source().lightFace(); - - if (front && direction == facing) - return; - if (!front && direction == facing.getOpposite()) - return; - if (isDouble && topSlab && direction == facing) - return; - if (isDouble && !topSlab && direction == facing.getOpposite()) - return; - - assembleQuad(context, bb, normalScaledN8); - } - - //Used in Beams public static void quadShift(CopycatRenderContext context, Vec3i rowShiftNormal, Vec3i columnShiftNormal, AABB bb1, Vec3 offset) { Direction direction = context.source().lightFace(); diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/PlatformModelUtilsImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/PlatformModelUtilsImpl.java index 149989bd4..f1e17b256 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/PlatformModelUtilsImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/PlatformModelUtilsImpl.java @@ -15,26 +15,6 @@ public class PlatformModelUtilsImpl { - //Used in Slabs - public static , Destination extends List> void cullFacing(Direction facing, CopycatRenderContext context, boolean front, boolean topSlab, boolean isDouble, AABB bb, Vec3 normalScaledN8) { - for (int i = 0; i < context.source().size(); i++) { - BakedQuad quad = context.source().get(i); - Direction direction = quad.getDirection(); - - if (front && direction == facing) - continue; - if (!front && direction == facing.getOpposite()) - continue; - if (isDouble && topSlab && direction == facing) - continue; - if (isDouble && !topSlab && direction == facing.getOpposite()) - continue; - - assembleQuad(quad, context.destination(), bb, normalScaledN8); - } - } - - //Used in Beams public static , Destination extends List> void quadShift(CopycatRenderContext context, Vec3i rowShiftNormal, Vec3i columnShiftNormal, AABB bb1, Vec3 offset) { for (int i = 0; i < context.source().size(); i++) { From f195f6fc987ffc8089347aa0bcc2c01f7a63cc35 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 09:34:46 +0800 Subject: [PATCH 27/71] Fix CT toggle for slabs --- .../model/multistate/forge/MultiStateCopycatModel.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java index f1ca931c8..e32ab6ec6 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java @@ -1,6 +1,8 @@ package com.copycatsplus.copycats.content.copycat.base.model.multistate.forge; +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateTextureAtlasSprite; import com.simibubi.create.foundation.model.BakedModelWrapperWithData; import com.simibubi.create.foundation.utility.Iterate; @@ -15,6 +17,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.client.model.data.ModelProperty; @@ -57,7 +60,12 @@ protected ModelData.Builder gatherModelData(ModelData.Builder builder, BlockAndT Vec3i inner = copycatBlock.getVectorFromProperty(state, s.getKey()); ScaledBlockAndTintGetterForge scaledWorld = new ScaledBlockAndTintGetterForge(s.getKey(), world, pos, inner, copycatBlock.vectorScale(state), p -> true); ScaledBlockAndTintGetterForge filteredWorld = new ScaledBlockAndTintGetterForge(s.getKey(), world, pos, inner, copycatBlock.vectorScale(state), - targetPos -> copycatBlock.canConnectTexturesToward(s.getKey(), scaledWorld, pos, targetPos, state)); + targetPos -> { + BlockEntity be = world.getBlockEntity(pos); + if (be instanceof MultiStateCopycatBlockEntity mscbe) + if (!mscbe.getMaterialItemStorage().getMaterialItem(s.getKey()).enableCT()) return false; + return copycatBlock.canConnectTexturesToward(s.getKey(), scaledWorld, pos, targetPos, state); + }); return getModelOf(s.getValue()).getModelData( filteredWorld, pos, s.getValue(), ModelData.EMPTY); From ab99b4c15452d74cd091ce0ee00f2cb4cdc41e16 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 10:06:58 +0800 Subject: [PATCH 28/71] Fix CT on fabric --- .../model/fabric/FilteredCopycatModel.java | 43 +++++++++++++++++++ .../base/model/fabric/SimpleCopycatModel.java | 5 +-- .../fabric/MultiStateCopycatModel.java | 10 ++++- .../forge/MultiStateCopycatModel.java | 1 - 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java new file mode 100644 index 000000000..b53136740 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java @@ -0,0 +1,43 @@ +package com.copycatsplus.copycats.content.copycat.base.model.fabric; + +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatModel; +import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.function.Supplier; + +/** + * A Fabric-specific class to implement canConnectTexturesToward and CT toggling logic + */ +public abstract class FilteredCopycatModel extends CopycatModel { + public FilteredCopycatModel(BakedModel originalModel) { + super(originalModel); + } + + @Override + protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { + if (state.getBlock() instanceof CopycatBlock copycatBlock) { + FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { + BlockEntity be = blockView.getBlockEntity(pos); + if (be instanceof CTCopycatBlockEntity ctbe) + if (!ctbe.isCTEnabled()) + return false; + return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); + }); + emitBlockQuadsFiltered(filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } else { + emitBlockQuadsFiltered(blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } + } + + protected abstract void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData); +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java index 603b036e7..36004f28b 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java @@ -2,7 +2,6 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.CopycatRenderContextFabric; -import com.simibubi.create.content.decoration.copycat.CopycatModel; import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -18,7 +17,7 @@ import static com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.assembleQuad; -public class SimpleCopycatModel extends CopycatModel { +public class SimpleCopycatModel extends FilteredCopycatModel { private final SimpleCopycatPart part; @@ -28,7 +27,7 @@ public SimpleCopycatModel(BakedModel originalModel, SimpleCopycatPart part) { } @Override - protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { + protected void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { BakedModel model = getModelOf(material); // Use a mesh to defer quad emission since quads cannot be emitted inside a transform diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java index 2a709c7b5..3dee58c1f 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java @@ -3,6 +3,7 @@ import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.content.copycat.base.multistate.MaterialItemStorage; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Iterate; @@ -26,6 +27,7 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; @@ -113,7 +115,13 @@ public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, Block Vec3i inner = copycatBlock.getVectorFromProperty(state, entry.getKey()); ScaledBlockAndTintGetter scaledWorld = new ScaledBlockAndTintGetter(entry.getKey(), blockView, pos, inner, copycatBlock.vectorScale(state), p -> true); innerBlockView = new ScaledBlockAndTintGetter(entry.getKey(), blockView, pos, inner, copycatBlock.vectorScale(state), - targetPos -> copycatBlock.canConnectTexturesToward(entry.getKey(), scaledWorld, pos, targetPos, state)); + targetPos -> { + BlockEntity be = blockView.getBlockEntity(pos); + if (be instanceof MultiStateCopycatBlockEntity mscbe) + if (!mscbe.getMaterialItemStorage().getMaterialItem(entry.getKey()).enableCT()) + return false; + return copycatBlock.canConnectTexturesToward(entry.getKey(), scaledWorld, pos, targetPos, state); + }); } emitBlockQuadsInner(entry.getKey(), innerBlockView, state, pos, randomSupplier, context, entry.getValue(), cullFaceRemovalData, occlusionData); diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java index e32ab6ec6..4df1f3938 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java @@ -1,6 +1,5 @@ package com.copycatsplus.copycats.content.copycat.base.model.multistate.forge; -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateTextureAtlasSprite; From ad7b2673ef05e32c4620f5663d61cea6f1e1bae7 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 11:05:03 +0800 Subject: [PATCH 29/71] Generalize slope model --- .../copycat/slope/CopycatSlopeModel.java | 125 +++++++++++------- .../CopycatVerticalSlopeModel.java | 4 +- 2 files changed, 81 insertions(+), 48 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java index 1365dda3e..a8e350c07 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -27,102 +27,135 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex boolean flipY = half == Half.TOP; GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); if (enhanced) - assembleSlope(context, transform, 16, 0, 3); + assembleSlope(context, transform, 16, 3); else - assembleSlope(context, transform, 16, 0); + assembleSlope(context, transform, 16); } - public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double minHeight) { + public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight) { assemblePiece(context, transform, vec3(0, 0, 0), aabb(16, 16, 16), cull(NORTH), - updateUV(slope(Direction.UP, (a, b) -> map(0, 16, minHeight, maxHeight, b))) + updateUV(slope(Direction.UP, (a, b) -> map(0, 16, 0, maxHeight, b))) ); } - public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double minHeight, double margin) { - final double angle = Math.atan2(maxHeight - minHeight, 16) / 2; - final double marginAdj = margin / Math.tan(angle); - final double midLength = Math.sqrt((maxHeight - minHeight) * (maxHeight - minHeight) + 16 * 16) - 2 * marginAdj; - final double marginAdjExcess = marginAdj - Math.floor(marginAdj); - final double alignedLength = ((int) Math.floor(midLength + 2 * marginAdjExcess)) % 2 == 0 - ? Math.floor(midLength + 2 * marginAdjExcess) - 2 * marginAdjExcess - : Math.floor(midLength + 2 * marginAdjExcess) + 1 - 2 * marginAdjExcess; + public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double margin) { + final double angleBottom = Math.toDegrees(Math.atan2(maxHeight, 16)); + final double marginAdjBottom = margin / Math.tan(Math.toRadians(angleBottom) / 2); + final double angleTop = Math.toDegrees(Math.atan2(16, maxHeight)); + final double marginAdjTop = margin / Math.tan(Math.toRadians(angleTop) / 2); + + final double halfLength = Math.sqrt(maxHeight * maxHeight + 16 * 16) / 2; + + final double midLengthBottom = halfLength - marginAdjBottom; + final double marginAdjExcessBottom = marginAdjBottom - Math.floor(marginAdjBottom); + final double midLengthTop = halfLength - marginAdjTop; + final double marginAdjExcessTop = marginAdjTop - Math.floor(marginAdjTop); + + final double alignedLengthBottom = Math.floor(midLengthBottom + marginAdjExcessBottom) - marginAdjExcessBottom; + final double alignedLengthTop = Math.floor(midLengthTop + marginAdjExcessTop) - marginAdjExcessTop; assemblePiece(context, transform, vec3(0, 0, 0), - aabb(16, 16, marginAdj), + aabb(16, 16, marginAdjBottom), cull(UP | NORTH | SOUTH), - updateUV(slope(Direction.UP, (a, b) -> map(0, marginAdj, 0, margin, b))) + updateUV(slope(Direction.UP, (a, b) -> map(0, marginAdjBottom, 0, margin, b))) ); assemblePiece(context, transform, - vec3(0, 0, marginAdj), - aabb(16, 16, 16 - margin - marginAdj).move(0, 0, marginAdj), + vec3(0, 0, marginAdjBottom), + aabb(16, 16, 16 - margin - marginAdjBottom).move(0, 0, marginAdjBottom), cull(UP | NORTH | SOUTH), - updateUV(slope(Direction.UP, (a, b) -> map(marginAdj, 16 - margin, margin, 16 - marginAdj, b))) - ); - assemblePiece(context, - transform, - vec3(0, 0, 16 - margin), - aabb(16, 16, margin).move(0, 0, 16 - margin), - cull(UP | NORTH), - updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, 16 - marginAdj, 16, b))) + updateUV(slope(Direction.UP, (a, b) -> map(marginAdjBottom, 16 - margin, margin, maxHeight - marginAdjTop, b))) ); + if (maxHeight == 16) { + assemblePiece(context, + transform, + vec3(0, 0, 16 - margin), + aabb(16, 16, margin).move(0, 0, 16 - margin), + cull(UP | NORTH), + updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, maxHeight - marginAdjTop, maxHeight, b))) + ); + } else { + assemblePiece(context, + transform, + vec3(0, 0, 16 - margin), + aabb(16, maxHeight / 2, margin).move(0, 0, 16 - margin), + cull(UP | NORTH) + ); + assemblePiece(context, + transform, + vec3(0, 16 - maxHeight / 2, 16 - margin), + aabb(16, maxHeight / 2, margin).move(0, 16 - maxHeight / 2, 16 - margin), + cull(UP | DOWN | NORTH), + scale( + pivot(16, 16, 16), + scale(1, 32 / maxHeight, 1) + ), + updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, 16 - marginAdjTop / maxHeight * 32, 16, b))), + scale( + pivot(16, 16, 16), + scale(1, maxHeight / 32, 1) + ), + translate(0, -16 + maxHeight, 0) + ); + } assemblePiece(context, transform, vec3(0, 0, 0), - aabb(16, 16, marginAdj), + aabb(16, 16, marginAdjBottom), cull(DOWN | NORTH | SOUTH), - updateUV(slope(Direction.DOWN, (a, b) -> map(0, marginAdj, 0, margin, b))), + updateUV(slope(Direction.DOWN, (a, b) -> map(0, marginAdjBottom, 0, margin, b))), translate(0, -16, 0), rotate( pivot(0, 0, 0), - angle(-45, 0, 0) + angle(-angleBottom, 0, 0) ) ); assemblePiece(context, transform, - vec3(0, 16 - margin, 16 - alignedLength / 2), - aabb(16, margin, alignedLength / 2).move(0, 16 - margin, marginAdj), + vec3(0, maxHeight - margin, 16 - alignedLengthBottom), + aabb(16, margin, alignedLengthBottom).move(0, 16 - margin, marginAdjBottom), cull(DOWN | NORTH | SOUTH), scale( - pivot(16, 16, 16), - scale(1, 1, midLength / alignedLength) + pivot(16, maxHeight, 16), + scale(1, 1, midLengthBottom / alignedLengthBottom) ), - translate(0, 0, -marginAdj - midLength / 2), + translate(0, 0, -halfLength), rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) + pivot(16, maxHeight, 16), + angle(-angleBottom, 0, 0) ) ); assemblePiece(context, transform, - vec3(0, 16 - margin, 16 - alignedLength / 2), - aabb(16, margin, alignedLength / 2).move(0, 16 - margin, 16 - marginAdj - alignedLength / 2), + vec3(0, maxHeight - margin, 16 - alignedLengthTop), + aabb(16, margin, alignedLengthTop).move(0, 16 - margin, 16 - marginAdjTop - alignedLengthTop), cull(DOWN | NORTH | SOUTH), scale( - pivot(16, 16, 16), - scale(1, 1, midLength / alignedLength) + pivot(16, maxHeight, 16), + scale(1, 1, midLengthTop / alignedLengthTop) ), - translate(0, 0, -marginAdj), + translate(0, 0, -marginAdjTop), rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) + pivot(16, maxHeight, 16), + angle(-angleBottom, 0, 0) ) ); assemblePiece(context, transform, - vec3(0, 0, 16 - marginAdj), - aabb(16, 16, marginAdj).move(0, 0, 16 - marginAdj), + vec3(0, 0, 16 - marginAdjTop), + aabb(16, 16, marginAdjTop).move(0, 0, 16 - marginAdjTop), cull(DOWN | NORTH | SOUTH), - updateUV(slope(Direction.DOWN, (a, b) -> map(16 - marginAdj, 16, margin, 0, b))), + updateUV(slope(Direction.DOWN, (a, b) -> map(16 - marginAdjTop, 16, margin, 0, b))), + translate(0, -16 + maxHeight, 0), rotate( - pivot(16, 16, 16), - angle(-45, 0, 0) + pivot(16, maxHeight, 16), + angle(-angleBottom, 0, 0) ) ); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java index 0cc359ce2..9e11fc409 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java @@ -30,8 +30,8 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex int rot = (int) facing.toYRot(); GlobalTransform transform = t -> t.rotateZ(-90).rotateY(rot); if (enhanced) - CopycatSlopeModel.assembleSlope(context, transform, 16, 0, 3); + CopycatSlopeModel.assembleSlope(context, transform, 16, 3); else - CopycatSlopeModel.assembleSlope(context, transform, 16, 0); + CopycatSlopeModel.assembleSlope(context, transform, 16); } } From bfbc7496e23f85271ad03560f24feabd2d81ec33 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 11:09:49 +0800 Subject: [PATCH 30/71] Fix negative length when maxHeight is small --- .../copycats/content/copycat/slope/CopycatSlopeModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java index a8e350c07..35e15c397 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -55,7 +55,7 @@ public static void assembleSlope(CopycatRenderContext context, GlobalTrans final double midLengthTop = halfLength - marginAdjTop; final double marginAdjExcessTop = marginAdjTop - Math.floor(marginAdjTop); - final double alignedLengthBottom = Math.floor(midLengthBottom + marginAdjExcessBottom) - marginAdjExcessBottom; + final double alignedLengthBottom = Math.abs(Math.floor(midLengthBottom + marginAdjExcessBottom) - marginAdjExcessBottom); final double alignedLengthTop = Math.floor(midLengthTop + marginAdjExcessTop) - marginAdjExcessTop; assemblePiece(context, From 1a4bd7d9872fea541d4a53c25df6aee6154e842c Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 12:36:50 +0800 Subject: [PATCH 31/71] Add slope layers --- .../copycats/CCBlockEntityTypes.java | 3 +- .../com/copycatsplus/copycats/CCBlocks.java | 12 + .../copycatsplus/copycats/CCCreativeTabs.java | 3 +- .../com/copycatsplus/copycats/CCShapes.java | 51 +++- .../copycat/slope/CopycatSlopeModel.java | 185 ++++++++++++- .../slope_layer/CopycatSlopeLayerBlock.java | 248 ++++++++++++++++++ .../slope_layer/CopycatSlopeLayerModel.java | 33 +++ .../CopycatVerticalSlopeModel.java | 13 +- .../datagen/recipes/CCStandardRecipes.java | 2 + .../copycats/lang/default/tooltips.json | 17 ++ .../block/copycat_base/slope_layer.json | 38 +++ .../blockstates/copycat_slope_layer.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 18 ++ .../resources/assets/copycats/lang/en_us.json | 18 ++ .../models/item/copycat_slope_layer.json | 3 + .../stonecutting/copycat_slope_layer.json | 33 +++ .../blocks/copycat_slope_layer.json | 238 +++++++++++++++++ .../stonecutting/copycat_slope_layer.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../blockstates/copycat_slope_layer.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 18 ++ .../resources/assets/copycats/lang/en_us.json | 18 ++ .../models/item/copycat_slope_layer.json | 3 + .../stonecutting/copycat_slope_layer.json | 33 +++ .../blocks/copycat_slope_layer.json | 238 +++++++++++++++++ .../stonecutting/copycat_slope_layer.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- 29 files changed, 1237 insertions(+), 30 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerModel.java create mode 100644 common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json create mode 100644 fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json create mode 100644 fabric/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json create mode 100644 fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json create mode 100644 fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json create mode 100644 fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json create mode 100644 forge/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json create mode 100644 forge/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json create mode 100644 forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json create mode 100644 forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json create mode 100644 forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java index debb999ce..80c3c72c2 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java @@ -35,7 +35,8 @@ public class CCBlockEntityTypes { CCBlocks.COPYCAT_HEAVY_WEIGHTED_PRESSURE_PLATE, CCBlocks.COPYCAT_VERTICAL_STAIRS, CCBlocks.COPYCAT_SLOPE, - CCBlocks.COPYCAT_VERTICAL_SLOPE + CCBlocks.COPYCAT_VERTICAL_SLOPE, + CCBlocks.COPYCAT_SLOPE_LAYER ) .register(); diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index f087043f9..26a20f139 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -42,6 +42,8 @@ import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceModel; import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeBlock; import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; +import com.copycatsplus.copycats.content.copycat.slope_layer.CopycatSlopeLayerBlock; +import com.copycatsplus.copycats.content.copycat.slope_layer.CopycatSlopeLayerModel; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsBlock; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsEnhancedModel; import com.copycatsplus.copycats.content.copycat.stairs.CopycatStairsModel; @@ -497,6 +499,16 @@ public class CCBlocks { .transform(customItemModel("copycat_base", "vertical_slope")) .register(); + public static final BlockEntry COPYCAT_SLOPE_LAYER = + REGISTRATE.block("copycat_slope_layer", CopycatSlopeLayerBlock::new) + .transform(BuilderTransformers.copycat()) + .transform(FeatureToggle.register(FeatureCategory.SLOPES)) + .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeLayerModel(false), new CopycatSlopeLayerModel(true)))) + .loot(CCLootGen.build(CCLootGen.lootForLayers())) + .item() + .transform(customItemModel("copycat_base", "slope_layer")) + .register(); + public static @Nullable BlockEntry COPYCAT_TEST_BLOCK; @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index c1343ea20..d3ae18911 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -40,7 +40,8 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_WOODEN_BUTTON, CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, CCBlocks.COPYCAT_SLOPE, - CCBlocks.COPYCAT_VERTICAL_SLOPE + CCBlocks.COPYCAT_VERTICAL_SLOPE, + CCBlocks.COPYCAT_SLOPE_LAYER ); @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java index 238f1ab72..10e578d04 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java @@ -140,29 +140,68 @@ public class CCShapes { private static final int SLOPE_SUBDIVISIONS = 16; public static final VoxelShaper SLOPE_BOTTOM = shape(Shapes.empty()).build((voxelShape, direction) -> { VoxelShape shape = Shapes.empty(); - for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { - shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 0, 0, 1, 1 - 1d / SLOPE_SUBDIVISIONS * i, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + for (int i = 0; i < SLOPE_SUBDIVISIONS - 1; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 0, 0, 1, 1 - 1d / SLOPE_SUBDIVISIONS * (i + 1), 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); } shape = shape.optimize(); return shape(shape).forDirectional(Direction.NORTH); }, Direction.SOUTH); public static final VoxelShaper SLOPE_TOP = shape(Shapes.empty()).build((voxelShape, direction) -> { VoxelShape shape = Shapes.empty(); - for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { - shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 1d / SLOPE_SUBDIVISIONS * i, 0, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + for (int i = 0; i < SLOPE_SUBDIVISIONS - 1; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 1d / SLOPE_SUBDIVISIONS * (i + 1), 0, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); } shape = shape.optimize(); return shape(shape).forDirectional(Direction.NORTH); }, Direction.SOUTH); public static final VoxelShaper SLOPE_LEFT = shape(Shapes.empty()).build((voxelShape, direction) -> { VoxelShape shape = Shapes.empty(); - for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { - shape = Shapes.joinUnoptimized(shape, Shapes.box(1 - 1d / SLOPE_SUBDIVISIONS * (i + 1), 0, 1d / SLOPE_SUBDIVISIONS * i, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + for (int i = 0; i < SLOPE_SUBDIVISIONS - 1; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(1 - 1d / SLOPE_SUBDIVISIONS * (i + 1), 0, 1d / SLOPE_SUBDIVISIONS * (i + 1), 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 2)), BooleanOp.OR); } shape = shape.optimize(); return shape(shape).forDirectional(Direction.SOUTH); }, Direction.SOUTH); + private static BiFunction slopeLayerBottom(double minHeight, double maxHeight) { + return (voxelShape, direction) -> { + VoxelShape shape = Shapes.empty(); + for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 0, 1d / SLOPE_SUBDIVISIONS * i, 1, minHeight + (maxHeight - minHeight) / SLOPE_SUBDIVISIONS * i, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + } + shape = shape.optimize(); + return shape(shape).forDirectional(Direction.SOUTH); + }; + } + + public static final VoxelShaper SLOPE_LAYER_BOTTOM_1 = shape(Shapes.empty()).build(slopeLayerBottom(0, 4 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_2 = shape(Shapes.empty()).build(slopeLayerBottom(0, 8 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_3 = shape(Shapes.empty()).build(slopeLayerBottom(0, 12 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_4 = shape(Shapes.empty()).build(slopeLayerBottom(0, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_5 = shape(Shapes.empty()).build(slopeLayerBottom(4 / 16d, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_6 = shape(Shapes.empty()).build(slopeLayerBottom(8 / 16d, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_BOTTOM_7 = shape(Shapes.empty()).build(slopeLayerBottom(12 / 16d, 1), Direction.SOUTH); + + private static BiFunction slopeLayerTop(double minHeight, double maxHeight) { + return (voxelShape, direction) -> { + VoxelShape shape = Shapes.empty(); + for (int i = 0; i < SLOPE_SUBDIVISIONS; i++) { + shape = Shapes.joinUnoptimized(shape, Shapes.box(0, 1d - minHeight - (maxHeight - minHeight) / SLOPE_SUBDIVISIONS * i, 1d / SLOPE_SUBDIVISIONS * i, 1, 1, 1d / SLOPE_SUBDIVISIONS * (i + 1)), BooleanOp.OR); + } + shape = shape.optimize(); + return shape(shape).forDirectional(Direction.SOUTH); + }; + } + + public static final VoxelShaper SLOPE_LAYER_TOP_1 = shape(Shapes.empty()).build(slopeLayerTop(0, 4 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_2 = shape(Shapes.empty()).build(slopeLayerTop(0, 8 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_3 = shape(Shapes.empty()).build(slopeLayerTop(0, 12 / 16d), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_4 = shape(Shapes.empty()).build(slopeLayerTop(0, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_5 = shape(Shapes.empty()).build(slopeLayerTop(4 / 16d, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_6 = shape(Shapes.empty()).build(slopeLayerTop(8 / 16d, 1), Direction.SOUTH); + public static final VoxelShaper SLOPE_LAYER_TOP_7 = shape(Shapes.empty()).build(slopeLayerTop(12 / 16d, 1), Direction.SOUTH); + + private static Builder shape(VoxelShape shape) { return new Builder(shape); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java index 35e15c397..40adb9842 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeModel.java @@ -26,13 +26,33 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex int rot = (int) facing.toYRot(); boolean flipY = half == Half.TOP; GlobalTransform transform = t -> t.flipY(flipY).rotateY(rot); - if (enhanced) - assembleSlope(context, transform, 16, 3); - else - assembleSlope(context, transform, 16); + assembleSlope(context, transform, 0, 16, enhanced); } - public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight) { + public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double minHeight, double maxHeight, boolean enhanced) { + if (minHeight == 0) { + if (enhanced) { + assembleTriangularSlope(context, transform, maxHeight, getMarginForHeight(maxHeight)); + } else { + assembleTriangularSlope(context, transform, maxHeight); + } + } else { + if (enhanced) { + assembleTrapezoidSlope(context, transform, minHeight, maxHeight, Math.min(2, getMarginForHeight(maxHeight))); + } else { + assembleTrapezoidSlope(context, transform, minHeight, maxHeight); + } + } + } + + private static double getMarginForHeight(double maxHeight) { + if (maxHeight <= 2.5) return 0.5; + if (maxHeight <= 4.5) return 1; + if (maxHeight <= 8.5) return 2; + return 3; + } + + public static void assembleTriangularSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight) { assemblePiece(context, transform, vec3(0, 0, 0), @@ -42,7 +62,17 @@ public static void assembleSlope(CopycatRenderContext context, GlobalTrans ); } - public static void assembleSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double margin) { + public static void assembleTrapezoidSlope(CopycatRenderContext context, GlobalTransform transform, double minHeight, double maxHeight) { + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, 16), + cull(0), + updateUV(slope(Direction.UP, (a, b) -> map(0, 16, minHeight, maxHeight, b))) + ); + } + + public static void assembleTriangularSlope(CopycatRenderContext context, GlobalTransform transform, double maxHeight, double margin) { final double angleBottom = Math.toDegrees(Math.atan2(maxHeight, 16)); final double marginAdjBottom = margin / Math.tan(Math.toRadians(angleBottom) / 2); final double angleTop = Math.toDegrees(Math.atan2(16, maxHeight)); @@ -159,4 +189,147 @@ public static void assembleSlope(CopycatRenderContext context, GlobalTrans ) ); } + + public static void assembleTrapezoidSlope(CopycatRenderContext context, GlobalTransform transform, double minHeight, double maxHeight, double margin) { + final double angleBottom = Math.toDegrees(Math.atan2(maxHeight - minHeight, 16)) + 90; + final double marginAdjBottom = margin / Math.tan(Math.toRadians(angleBottom) / 2); + final double angleTop = Math.toDegrees(Math.atan2(16, maxHeight - minHeight)); + final double marginAdjTop = margin / Math.tan(Math.toRadians(angleTop) / 2); + + final double halfLength = Math.sqrt((maxHeight - minHeight) * (maxHeight - minHeight) + 16 * 16) / 2; + + final double midLengthBottom = halfLength - marginAdjBottom; + final double marginAdjExcessBottom = marginAdjBottom - Math.floor(marginAdjBottom); + final double midLengthTop = halfLength - marginAdjTop; + final double marginAdjExcessTop = marginAdjTop - Math.floor(marginAdjTop); + + final double alignedLengthBottom = Math.abs(Math.floor(midLengthBottom + marginAdjExcessBottom) - marginAdjExcessBottom); + final double alignedLengthTop = Math.floor(midLengthTop + marginAdjExcessTop) - marginAdjExcessTop; + + if (minHeight == 16 || minHeight == 0) { + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, margin), + cull(UP | SOUTH), + updateUV(slope(Direction.UP, (a, b) -> map(0, margin, minHeight, minHeight - marginAdjBottom, b))) + ); + } else { + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, minHeight / 2, margin).move(0, 0, 0), + cull(UP | SOUTH) + ); + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, minHeight / 2, margin).move(0, 16 - minHeight / 2, 0), + cull(UP | DOWN | SOUTH), + scale( + pivot(0, 0, 0), + scale(1, 32 / minHeight, 1) + ), + updateUV(slope(Direction.UP, (a, b) -> map(0, margin, 16, 16 - marginAdjBottom / minHeight * 32, b))), + scale( + pivot(0, 0, 0), + scale(1, minHeight / 32, 1) + ), + translate(0, minHeight / 2, 0) + ); + } + assemblePiece(context, + transform, + vec3(0, 0, margin), + aabb(16, 16, 16 - margin * 2).move(0, 0, margin), + cull(UP | NORTH | SOUTH), + updateUV(slope(Direction.UP, (a, b) -> map(margin, 16 - margin, minHeight - marginAdjBottom, maxHeight - marginAdjTop, b))) + ); + if (maxHeight == 16 || maxHeight == 0) { + assemblePiece(context, + transform, + vec3(0, 0, 16 - margin), + aabb(16, 16, margin).move(0, 0, 16 - margin), + cull(UP | NORTH), + updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, maxHeight - marginAdjTop, maxHeight, b))) + ); + } else { + assemblePiece(context, + transform, + vec3(0, 0, 16 - margin), + aabb(16, maxHeight / 2, margin).move(0, 0, 16 - margin), + cull(UP | NORTH) + ); + assemblePiece(context, + transform, + vec3(0, 16 - maxHeight / 2, 16 - margin), + aabb(16, maxHeight / 2, margin).move(0, 16 - maxHeight / 2, 16 - margin), + cull(UP | DOWN | NORTH), + scale( + pivot(16, 16, 16), + scale(1, 32 / maxHeight, 1) + ), + updateUV(slope(Direction.UP, (a, b) -> map(16 - margin, 16, 16 - marginAdjTop / maxHeight * 32, 16, b))), + scale( + pivot(16, 16, 16), + scale(1, maxHeight / 32, 1) + ), + translate(0, -16 + maxHeight, 0) + ); + } + assemblePiece(context, + transform, + vec3(0, 0, 0), + aabb(16, 16, marginAdjBottom), + cull(DOWN | NORTH | SOUTH), + updateUV(slope(Direction.DOWN, (a, b) -> map(0, marginAdjBottom, 0, margin, b))), + translate(0, -16 + minHeight, 0), + rotate( + pivot(0, minHeight, 0), + angle(90 - angleBottom, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, maxHeight - margin, 16 - alignedLengthBottom), + aabb(16, margin, alignedLengthBottom).move(0, 16 - margin, marginAdjBottom), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, maxHeight, 16), + scale(1, 1, midLengthBottom / alignedLengthBottom) + ), + translate(0, 0, -halfLength), + rotate( + pivot(16, maxHeight, 16), + angle(90 - angleBottom, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, maxHeight - margin, 16 - alignedLengthTop), + aabb(16, margin, alignedLengthTop).move(0, 16 - margin, 16 - marginAdjTop - alignedLengthTop), + cull(DOWN | NORTH | SOUTH), + scale( + pivot(16, maxHeight, 16), + scale(1, 1, midLengthTop / alignedLengthTop) + ), + translate(0, 0, -marginAdjTop), + rotate( + pivot(16, maxHeight, 16), + angle(90 - angleBottom, 0, 0) + ) + ); + assemblePiece(context, + transform, + vec3(0, 0, 16 - marginAdjTop), + aabb(16, 16, marginAdjTop).move(0, 0, 16 - marginAdjTop), + cull(DOWN | NORTH | SOUTH), + updateUV(slope(Direction.DOWN, (a, b) -> map(16 - marginAdjTop, 16, margin, 0, b))), + translate(0, -16 + maxHeight, 0), + rotate( + pivot(16, maxHeight, 16), + angle(90 - angleBottom, 0, 0) + ) + ); + } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java new file mode 100644 index 000000000..87c336cbd --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java @@ -0,0 +1,248 @@ +package com.copycatsplus.copycats.content.copycat.slope_layer; + +import com.copycatsplus.copycats.CCShapes; +import com.copycatsplus.copycats.Copycats; +import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.IStateType; +import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement; +import com.simibubi.create.content.schematics.requirement.ItemRequirement; +import com.simibubi.create.foundation.utility.VoxelShaper; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.*; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import static net.minecraft.core.Direction.UP; + +public class CopycatSlopeLayerBlock extends CTWaterloggedCopycatBlock implements ISpecialBlockItemRequirement, IStateType { + + + public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final EnumProperty HALF = BlockStateProperties.HALF; + public static final IntegerProperty LAYERS = BlockStateProperties.LAYERS; + + private static final VoxelShaper[] BOTTOM_SHAPE_BY_LAYER = new VoxelShaper[]{ + CCShapes.EMPTY, + CCShapes.SLOPE_LAYER_BOTTOM_1, + CCShapes.SLOPE_LAYER_BOTTOM_2, + CCShapes.SLOPE_LAYER_BOTTOM_3, + CCShapes.SLOPE_LAYER_BOTTOM_4, + CCShapes.SLOPE_LAYER_BOTTOM_5, + CCShapes.SLOPE_LAYER_BOTTOM_6, + CCShapes.SLOPE_LAYER_BOTTOM_7, + CCShapes.LAYER_16PX + }; + private static final VoxelShaper[] TOP_SHAPE_BY_LAYER = new VoxelShaper[]{ + CCShapes.EMPTY, + CCShapes.SLOPE_LAYER_TOP_1, + CCShapes.SLOPE_LAYER_TOP_2, + CCShapes.SLOPE_LAYER_TOP_3, + CCShapes.SLOPE_LAYER_TOP_4, + CCShapes.SLOPE_LAYER_TOP_5, + CCShapes.SLOPE_LAYER_TOP_6, + CCShapes.SLOPE_LAYER_TOP_7, + CCShapes.LAYER_16PX + }; + + public CopycatSlopeLayerBlock(Properties pProperties) { + super(pProperties); + registerDefaultState(defaultBlockState() + .setValue(FACING, Direction.NORTH) + .setValue(HALF, Half.BOTTOM) + .setValue(LAYERS, 1) + ); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + super.createBlockStateDefinition(pBuilder.add(FACING, HALF, LAYERS)); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + BlockState stateForPlacement = super.getStateForPlacement(context); + assert stateForPlacement != null; + BlockPos blockPos = context.getClickedPos(); + BlockState state = context.getLevel().getBlockState(blockPos); + if (state.is(this)) { + if (state.getValue(LAYERS) < 8) + return state.cycle(LAYERS); + else { + Copycats.LOGGER.warn("Can't figure out where to place a slope layer! Please file an issue if you see this."); + return state; + } + } else { + Half half = context.getClickedFace() == Direction.DOWN + ? Half.TOP + : context.getClickedFace() == Direction.UP + ? Half.BOTTOM + : context.getClickLocation().y - context.getClickedPos().getY() > 0.5 + ? Half.TOP + : Half.BOTTOM; + return stateForPlacement + .setValue(FACING, context.getHorizontalDirection()) + .setValue(HALF, half); + } + } + + @SuppressWarnings("deprecation") + @Override + public boolean canBeReplaced(@NotNull BlockState pState, BlockPlaceContext pUseContext) { + ItemStack itemstack = pUseContext.getItemInHand(); + if (!itemstack.is(this.asItem())) return false; + if (pState.getValue(LAYERS) == 8) return false; + Half half = pState.getValue(HALF); + if (half == Half.TOP && pUseContext.getClickedFace() == Direction.DOWN) return true; + if (half == Half.BOTTOM && pUseContext.getClickedFace() == Direction.UP) return true; + return false; + } + + @Override + public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { + if (state.getValue(LAYERS) <= 1) + return super.onSneakWrenched(state, context); + + Level world = context.getLevel(); + BlockPos pos = context.getClickedPos(); + Player player = context.getPlayer(); + if (world instanceof ServerLevel serverLevel) { + if (player != null && !player.isCreative()) { + // Respect loot tables + List drops = Block.getDrops(state.setValue(LAYERS, 1), serverLevel, pos, world.getBlockEntity(pos), player, context.getItemInHand()); + for (ItemStack drop : drops) { + player.getInventory().placeItemBackInInventory(drop); + } + } + BlockPos up = pos.relative(Direction.UP); + // need to call updateShape before setBlock to schedule a tick for water + world.setBlockAndUpdate(pos, state.setValue(LAYERS, state.getValue(LAYERS) - 1).updateShape(Direction.UP, world.getBlockState(up), world, pos, up)); + playRemoveSound(world, pos); + } + return InteractionResult.SUCCESS; + } + + @Override + public ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity) { + return new ItemRequirement( + ItemRequirement.ItemUseType.CONSUME, + new ItemStack(asItem(), state.getValue(LAYERS)) + ); + } + + @Override + public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { + Direction facing = state.getValue(FACING); + BlockState toState = reader.getBlockState(toPos); + + return !toState.is(this); + } + + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, BlockState state) { + BlockState toState = reader.getBlockState(toPos); + if (!toState.is(this)) return false; + Direction facing = state.getValue(FACING); + + if (toPos.equals(fromPos.relative(facing))) return false; + + BlockPos diff = fromPos.subtract(toPos); + int coord = facing.getAxis().choose(diff.getX(), diff.getY(), diff.getZ()); + + if (!toState.is(this)) return coord != -facing.getAxisDirection().getStep(); + + if (isOccluded(state, toState, facing)) return true; + if (toState.setValue(WATERLOGGED, false) == state.setValue(WATERLOGGED, false) && coord == 0) return true; + return false; + } + + private static boolean isOccluded(BlockState state, BlockState other, Direction pDirection) { + state = state.setValue(WATERLOGGED, false); + other = other.setValue(WATERLOGGED, false); + Direction facing = state.getValue(FACING); + if (facing.getOpposite() == other.getValue(FACING) && pDirection == facing) return true; + if (other.getValue(FACING) != facing) return false; + return pDirection.getAxis() != facing.getAxis(); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull BlockState rotate(BlockState state, Rotation rot) { + return state.setValue(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + @SuppressWarnings("deprecation") + public @NotNull BlockState mirror(BlockState state, Mirror mirrorIn) { + return state.rotate(mirrorIn.getRotation(state.getValue(FACING))); + } + + @SuppressWarnings("deprecation") + @Override + public boolean isPathfindable(@NotNull BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull PathComputationType pType) { + return switch (pType) { + case LAND -> pState.getValue(LAYERS) < 5 && pState.getValue(FACING).equals(UP); + default -> false; + }; + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull VoxelShape getShape(BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull CollisionContext pContext) { + return pState.getValue(HALF) == Half.TOP + ? TOP_SHAPE_BY_LAYER[pState.getValue(LAYERS)].get(pState.getValue(FACING)) + : BOTTOM_SHAPE_BY_LAYER[pState.getValue(LAYERS)].get(pState.getValue(FACING)); + } + + + public boolean supportsExternalFaceHiding(BlockState state) { + return true; + } + + + public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, Direction dir) { + Direction facing = state.getValue(FACING); + int layers = state.getValue(LAYERS); + if (state.is(this) == neighborState.is(this)) { + Direction neighborFacing = neighborState.getValue(FACING); + int neighborLayers = neighborState.getValue(LAYERS); + if (getMaterial(level, pos).skipRendering(getMaterial(level, pos.relative(dir)), dir.getOpposite())) { + return neighborFacing == facing && neighborLayers == layers || // cull the sides if two copycats of the same height are next to each other + // cull if both sides have a square block face + (neighborFacing == facing.getOpposite() || neighborLayers == 8) && facing == dir.getOpposite() || + (neighborFacing == facing.getOpposite() || layers == 8) && neighborFacing == dir || + layers == 8 && neighborLayers == 8; + } + } + return false; + } + + @Override + public boolean useShapeForLightOcclusion(BlockState state) { + return true; + } + + @Override + public float getShadeBrightness(BlockState state, BlockGetter level, BlockPos pos) { + return state.getValue(LAYERS) == 8 ? 0.2f : 1.0f; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerModel.java new file mode 100644 index 000000000..62b3423ce --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerModel.java @@ -0,0 +1,33 @@ +package com.copycatsplus.copycats.content.copycat.slope_layer; + +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; +import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Half; + +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; + +public class CopycatSlopeLayerModel implements SimpleCopycatPart { + + private final boolean enhanced; + + public CopycatSlopeLayerModel(boolean enhanced) { + this.enhanced = enhanced; + } + + @Override + public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { + int layer = state.getValue(CopycatSlopeLayerBlock.LAYERS); + Direction facing = state.getValue(CopycatSlopeLayerBlock.FACING); + Half half = state.getValue(CopycatSlopeLayerBlock.HALF); + + GlobalTransform transform = t -> t.rotateY((int) facing.toYRot()).flipY(half == Half.TOP); + + if (layer <= 4) + CopycatSlopeModel.assembleSlope(context, transform, 0, layer * 4, enhanced); + else + CopycatSlopeModel.assembleSlope(context, transform, (layer - 4) * 4, 16, enhanced); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java index 9e11fc409..53680b337 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeModel.java @@ -2,18 +2,10 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; -import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeBlock; import com.copycatsplus.copycats.content.copycat.slope.CopycatSlopeModel; -import com.simibubi.create.foundation.utility.Iterate; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Half; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import static com.copycatsplus.copycats.content.copycat.base.model.PlatformModelUtils.assembleVerticalStep; import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.CopycatRenderContext; public class CopycatVerticalSlopeModel implements SimpleCopycatPart { @@ -29,9 +21,6 @@ public void emitCopycatQuads(BlockState state, CopycatRenderContext contex Direction facing = state.getValue(CopycatVerticalSlopeBlock.FACING); int rot = (int) facing.toYRot(); GlobalTransform transform = t -> t.rotateZ(-90).rotateY(rot); - if (enhanced) - CopycatSlopeModel.assembleSlope(context, transform, 16, 3); - else - CopycatSlopeModel.assembleSlope(context, transform, 16); + CopycatSlopeModel.assembleSlope(context, transform, 0, 16, enhanced); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java index 8df7f824b..4edf6c594 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java @@ -173,6 +173,8 @@ public class CCStandardRecipes extends CopycatsRecipeProvider { GeneratedRecipe COPYCAT_VERTICAL_SLOPE = copycat(CCBlocks.COPYCAT_VERTICAL_SLOPE, 2); + GeneratedRecipe COPYCAT_SLOPE_LAYER = copycat(CCBlocks.COPYCAT_SLOPE_LAYER, 8); + String currentFolder = ""; diff --git a/common/src/main/resources/assets/copycats/lang/default/tooltips.json b/common/src/main/resources/assets/copycats/lang/default/tooltips.json index 0a2b9f69a..b25ef0bfb 100644 --- a/common/src/main/resources/assets/copycats/lang/default/tooltips.json +++ b/common/src/main/resources/assets/copycats/lang/default/tooltips.json @@ -4,6 +4,23 @@ "block.copycats.copycat_beam.tooltip.condition1": "When R-Clicked", "block.copycats.copycat_beam.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", "block.copycats.copycat_beam.tooltip.summary": "_Converts_ any _full block_ into a decorative beam.", + "block.copycats.copycat_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative slope.", + "block.copycats.copycat_vertical_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_vertical_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_vertical_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_vertical_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_vertical_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative vertical slope.", + "block.copycats.copycat_slope_layer.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope_layer.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope_layer.tooltip.behaviour3": "_Dismantles_ parts of the copycat _individually_.", + "block.copycats.copycat_slope_layer.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope_layer.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope_layer.tooltip.condition3": "When Wrenched while Sneaking", + "block.copycats.copycat_slope_layer.tooltip.summary": "_Converts_ any _full block_ into decorative sloped layers. Layers can be stacked till it reaches a full block in size.", "block.copycats.copycat_block.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_block.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", "block.copycats.copycat_block.tooltip.behaviour3": "???", diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json new file mode 100644 index 000000000..515e1cde7 --- /dev/null +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json @@ -0,0 +1,38 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "copycats:block/copycat_slope", + "2": "create:block/copycat_base", + "particle": "create:block/copycat_base" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "south": {"uv": [16, 0, 0, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#2"} + } + }, + { + "from": [4.6863, 0, 0], + "to": [16, 0, 16], + "rotation": {"angle": -45, "axis": "z", "origin": [16, 0, 0]}, + "faces": { + "up": {"uv": [0, 5, 16, 16], "rotation": 270, "texture": "#2"} + } + }, + { + "from": [-3.3137, 8, 0], + "to": [8, 8, 16], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "up": {"uv": [0, 0, 16, 11], "rotation": 270, "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json index f3484e0d4..45f5a91c5 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json @@ -96,6 +96,19 @@ "block.copycats.copycat_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_slope": "ǝdoןS ʇɐɔʎdoƆ", + "block.copycats.copycat_slope.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_slope.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_slope.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_slope.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_slope.tooltip.summary": "˙ǝdoןs ǝʌıʇɐɹoɔǝp ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_slope_layer": "ɹǝʎɐꞀ ǝdoןS ʇɐɔʎdoƆ", + "block.copycats.copycat_slope_layer.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_slope_layer.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_slope_layer.tooltip.behaviour3": "˙‾ʎןןɐnpıʌıpuı‾ ʇɐɔʎdoɔ ǝɥʇ ɟo sʇɹɐd ‾sǝןʇuɐɯsıᗡ‾", + "block.copycats.copycat_slope_layer.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝʞɔɐʇs ǝq uɐɔ sɹǝʎɐꞀ ˙sɹǝʎɐן pǝdoןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_stairs": "sɹıɐʇS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", @@ -126,6 +139,11 @@ "block.copycats.copycat_vertical_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_vertical_slope": "ǝdoןS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", + "block.copycats.copycat_vertical_slope.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_vertical_slope.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_vertical_slope.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_vertical_slope.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_vertical_slope.tooltip.summary": "˙ǝdoןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_vertical_stairs": "sɹıɐʇS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_us.json b/fabric/src/generated/resources/assets/copycats/lang/en_us.json index 22dcf343b..41fc0d822 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_us.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_us.json @@ -96,6 +96,19 @@ "block.copycats.copycat_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_slice.tooltip.summary": "_Converts_ any _full block_ into decorative slices. Slices can be enlarged till it reaches a full block in size.", "block.copycats.copycat_slope": "Copycat Slope", + "block.copycats.copycat_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative slope.", + "block.copycats.copycat_slope_layer": "Copycat Slope Layer", + "block.copycats.copycat_slope_layer.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope_layer.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope_layer.tooltip.behaviour3": "_Dismantles_ parts of the copycat _individually_.", + "block.copycats.copycat_slope_layer.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope_layer.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope_layer.tooltip.condition3": "When Wrenched while Sneaking", + "block.copycats.copycat_slope_layer.tooltip.summary": "_Converts_ any _full block_ into decorative sloped layers. Layers can be stacked till it reaches a full block in size.", "block.copycats.copycat_stairs": "Copycat Stairs", "block.copycats.copycat_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", @@ -126,6 +139,11 @@ "block.copycats.copycat_vertical_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_vertical_slice.tooltip.summary": "_Converts_ any _full block_ into decorative vertical slices. Slices can be enlarged till it reaches a full block in size.", "block.copycats.copycat_vertical_slope": "Copycat Vertical Slope", + "block.copycats.copycat_vertical_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_vertical_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_vertical_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_vertical_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_vertical_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative vertical slope.", "block.copycats.copycat_vertical_stairs": "Copycat Vertical Stairs", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json b/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json new file mode 100644 index 000000000..975e6f06b --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/slope_layer" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json new file mode 100644 index 000000000..646e98a32 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "c:zinc_ingots" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_slope_layer" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_slope_layer" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json new file mode 100644 index 000000000..77c5436a5 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json @@ -0,0 +1,238 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "1" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 1.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "2" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 2.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "3" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 3.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "4" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 4.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "5" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 5.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "6" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 6.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "7" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 7.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "8" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 8.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_slope_layer" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json new file mode 100644 index 000000000..5d941bbf2 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 8, + "ingredient": { + "tag": "c:zinc_ingots" + }, + "result": "copycats:copycat_slope_layer" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 32634e6d8..73f0a592a 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -27,6 +27,7 @@ "copycats:copycat_vertical_step", "copycats:copycat_wall", "copycats:copycat_slope", - "copycats:copycat_vertical_slope" + "copycats:copycat_vertical_slope", + "copycats:copycat_slope_layer" ] } \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 32634e6d8..73f0a592a 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -27,6 +27,7 @@ "copycats:copycat_vertical_step", "copycats:copycat_wall", "copycats:copycat_slope", - "copycats:copycat_vertical_slope" + "copycats:copycat_vertical_slope", + "copycats:copycat_slope_layer" ] } \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json b/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/blockstates/copycat_slope_layer.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/lang/en_ud.json b/forge/src/generated/resources/assets/copycats/lang/en_ud.json index f3484e0d4..45f5a91c5 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_ud.json @@ -96,6 +96,19 @@ "block.copycats.copycat_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_slope": "ǝdoןS ʇɐɔʎdoƆ", + "block.copycats.copycat_slope.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_slope.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_slope.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_slope.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_slope.tooltip.summary": "˙ǝdoןs ǝʌıʇɐɹoɔǝp ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_slope_layer": "ɹǝʎɐꞀ ǝdoןS ʇɐɔʎdoƆ", + "block.copycats.copycat_slope_layer.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_slope_layer.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_slope_layer.tooltip.behaviour3": "˙‾ʎןןɐnpıʌıpuı‾ ʇɐɔʎdoɔ ǝɥʇ ɟo sʇɹɐd ‾sǝןʇuɐɯsıᗡ‾", + "block.copycats.copycat_slope_layer.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", + "block.copycats.copycat_slope_layer.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝʞɔɐʇs ǝq uɐɔ sɹǝʎɐꞀ ˙sɹǝʎɐן pǝdoןs ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_stairs": "sɹıɐʇS ʇɐɔʎdoƆ", "block.copycats.copycat_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", @@ -126,6 +139,11 @@ "block.copycats.copycat_vertical_slice.tooltip.condition3": "buıʞɐǝuS ǝןıɥʍ pǝɥɔuǝɹM uǝɥM", "block.copycats.copycat_vertical_slice.tooltip.summary": "˙ǝzıs uı ʞɔoןq ןןnɟ ɐ sǝɥɔɐǝɹ ʇı ןןıʇ pǝbɹɐןuǝ ǝq uɐɔ sǝɔıןS ˙sǝɔıןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_vertical_slope": "ǝdoןS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", + "block.copycats.copycat_vertical_slope.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", + "block.copycats.copycat_vertical_slope.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", + "block.copycats.copycat_vertical_slope.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", + "block.copycats.copycat_vertical_slope.tooltip.condition2": "puɐH ʎʇdɯƎ ɥʇıʍ pǝʞɔıןƆ-ᴚ-ʞɐǝuS uǝɥM", + "block.copycats.copycat_vertical_slope.tooltip.summary": "˙ǝdoןs ןɐɔıʇɹǝʌ ǝʌıʇɐɹoɔǝp ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", "block.copycats.copycat_vertical_stairs": "sɹıɐʇS ןɐɔıʇɹǝΛ ʇɐɔʎdoƆ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/forge/src/generated/resources/assets/copycats/lang/en_us.json b/forge/src/generated/resources/assets/copycats/lang/en_us.json index 22dcf343b..41fc0d822 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_us.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_us.json @@ -96,6 +96,19 @@ "block.copycats.copycat_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_slice.tooltip.summary": "_Converts_ any _full block_ into decorative slices. Slices can be enlarged till it reaches a full block in size.", "block.copycats.copycat_slope": "Copycat Slope", + "block.copycats.copycat_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative slope.", + "block.copycats.copycat_slope_layer": "Copycat Slope Layer", + "block.copycats.copycat_slope_layer.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_slope_layer.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_slope_layer.tooltip.behaviour3": "_Dismantles_ parts of the copycat _individually_.", + "block.copycats.copycat_slope_layer.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_slope_layer.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_slope_layer.tooltip.condition3": "When Wrenched while Sneaking", + "block.copycats.copycat_slope_layer.tooltip.summary": "_Converts_ any _full block_ into decorative sloped layers. Layers can be stacked till it reaches a full block in size.", "block.copycats.copycat_stairs": "Copycat Stairs", "block.copycats.copycat_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", @@ -126,6 +139,11 @@ "block.copycats.copycat_vertical_slice.tooltip.condition3": "When Wrenched while Sneaking", "block.copycats.copycat_vertical_slice.tooltip.summary": "_Converts_ any _full block_ into decorative vertical slices. Slices can be enlarged till it reaches a full block in size.", "block.copycats.copycat_vertical_slope": "Copycat Vertical Slope", + "block.copycats.copycat_vertical_slope.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", + "block.copycats.copycat_vertical_slope.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", + "block.copycats.copycat_vertical_slope.tooltip.condition1": "When R-Clicked", + "block.copycats.copycat_vertical_slope.tooltip.condition2": "When Sneak-R-Clicked with Empty Hand", + "block.copycats.copycat_vertical_slope.tooltip.summary": "_Converts_ any _full block_ into a decorative vertical slope.", "block.copycats.copycat_vertical_stairs": "Copycat Vertical Stairs", "block.copycats.copycat_vertical_stairs.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_vertical_stairs.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/forge/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json b/forge/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json new file mode 100644 index 000000000..975e6f06b --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/models/item/copycat_slope_layer.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/slope_layer" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json new file mode 100644 index 000000000..29193b957 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_slope_layer.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "forge:ingots/zinc" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_slope_layer" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_slope_layer" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json new file mode 100644 index 000000000..77c5436a5 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_slope_layer.json @@ -0,0 +1,238 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "1" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 1.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "2" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 2.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "3" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 3.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "4" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 4.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "5" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 5.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "6" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 6.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "7" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 7.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "block": "copycats:copycat_slope_layer", + "condition": "minecraft:block_state_property", + "properties": { + "layers": "8" + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": 8.0, + "function": "minecraft:set_count" + } + ], + "name": "copycats:copycat_slope_layer" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_slope_layer" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json new file mode 100644 index 000000000..6511076da --- /dev/null +++ b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_slope_layer.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 8, + "ingredient": { + "tag": "forge:ingots/zinc" + }, + "result": "copycats:copycat_slope_layer" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index da749ddc4..2a8bb3211 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_step", "copycats:copycat_wall", "copycats:copycat_slope", - "copycats:copycat_vertical_slope" + "copycats:copycat_vertical_slope", + "copycats:copycat_slope_layer" ] } \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index da749ddc4..2a8bb3211 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_step", "copycats:copycat_wall", "copycats:copycat_slope", - "copycats:copycat_vertical_slope" + "copycats:copycat_vertical_slope", + "copycats:copycat_slope_layer" ] } \ No newline at end of file From 285ea39f18a1b13a7edad7026af130057d076eb4 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 12:47:29 +0800 Subject: [PATCH 32/71] Update item model of slope layer --- .../block/copycat_base/slope_layer.json | 26 ++++++------------ .../textures/block/copycat_slope_layer.png | Bin 0 -> 6612 bytes 2 files changed, 9 insertions(+), 17 deletions(-) create mode 100644 common/src/main/resources/assets/copycats/textures/block/copycat_slope_layer.png diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json index 515e1cde7..5162c7604 100644 --- a/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/slope_layer.json @@ -2,36 +2,28 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { - "1": "copycats:block/copycat_slope", + "1": "copycats:block/copycat_slope_layer", "2": "create:block/copycat_base", "particle": "create:block/copycat_base" }, "elements": [ { "from": [0, 0, 0], - "to": [16, 16, 16], + "to": [16, 6.62742, 16], "rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]}, "faces": { - "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, - "south": {"uv": [16, 0, 0, 16], "texture": "#1"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#2"}, + "north": {"uv": [0, 12, 16, 16], "texture": "#1"}, + "south": {"uv": [16, 12, 0, 16], "texture": "#1"}, + "west": {"uv": [0, 12, 16, 16], "texture": "#2"}, "down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#2"} } }, { - "from": [4.6863, 0, 0], - "to": [16, 0, 16], - "rotation": {"angle": -45, "axis": "z", "origin": [16, 0, 0]}, + "from": [0, 6.6274, 0], + "to": [17.31828, 6.6274, 16], + "rotation": {"angle": -22.5, "axis": "z", "origin": [0, 6.6274, 0]}, "faces": { - "up": {"uv": [0, 5, 16, 16], "rotation": 270, "texture": "#2"} - } - }, - { - "from": [-3.3137, 8, 0], - "to": [8, 8, 16], - "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, - "faces": { - "up": {"uv": [0, 0, 16, 11], "rotation": 270, "texture": "#2"} + "up": {"uv": [0, 0, 16, 16], "texture": "#2"} } } ] diff --git a/common/src/main/resources/assets/copycats/textures/block/copycat_slope_layer.png b/common/src/main/resources/assets/copycats/textures/block/copycat_slope_layer.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba033c7ec899e436bbabeb858a5b881fc209cc2 GIT binary patch literal 6612 zcmeHLcT`i^*1v=*O;8j;fe;idgmh9MBtVcNK|oX#1yXJxlq4k4gfbAZF*ZOQrHKud z(E+j3lq!N_MMNIbL{wDDFf$5@;CBPo_hxQ{OIfB zuBUCP4FG_irw79y0ANrR256~5Ma}WK^#Gu8EG{5W>d%tFMPeb39|gjtu_6!-%K1D1 zkhc~D2CeVQ*B=WrqN?dw&fQWYDafrdOBCuB?rE~J@oX1gFQ#kcA*1t($19Syj%r#Q zOqMw}v9}FX+T^7r)NM3-x#zZn*`x9hi;8&KtFng*cjKc^2%#|-q_0Az_wU2z_S7&| z4Ab8@rd0=b3|P1747J^Db9p%Z7}ao;K#xx@Z=$fVWBD%6Pet!Pa`B3wBXED*gSo>M z8>{1(cN#im)=r|Zj@eyr^mgIQ5d*nr7HGvf;%wSB^9R*5VtFSX+OXU?0)pd=Qupn- zhu2X{;?E~{A`-%Sa@_lI!y=DaIUU4`r z|Lsbglf%yYHX*Uy#!ua97NMh}D$nH>X}-R6`A$g`<)p((+%IifM{?2skZ!OD890I3 zfpOi?Ta;Z;gc`hk=oo)-t}I2x(DY%x*mR_HfHr-lMl!a*(RFTB5y%p|NXMzE z_iGzBUbIpCSad!VS4#)-4RzcoP4V-RE%g8}%1ot4#{h2FS>$PvVO4~o?XO$pbt2z5 zRj@TN%_Pl$kpr8}Fsamb?xLCMI_=#&FU7-X#-6!kv92F`hpEj19;oNzcJySH_077O z-nLm;tIp;mu+xs`W#CtNEeQK16Cb0<>`iF>of6n~~!u_^{ z#~S0|XZYv#tsZE4RmqhzzF}GVa)?{PiU#c95ARnJXYI>)~;IGW6g7iJw5}k_q68iv}V)M(%-SY)wkYk z?qv)h+j6!nEq>F9cxEl7F$N4Th2>vpkiB9=xjn+as7i6#A^WxCcgH^S)x!~8C;GSl z==F5*JVq47zW0f{8B@`j-&S@}FkCb6hum)#YST1=-eCppM)vJDsi%X6i5mvbTh%@C zHZ)KiUYIt2!EohKo5HqjJ;^l;wL4OC^|vCwM--S0b~5Vd9mRuJfxBxmch`^(McyzF z9?2X^w8%>BSUsz2%=*kofcutbr;pcxx7HgKmK;3!L`%c*W=#3L($nf)LkGG^+pHJb zy6c#i4UC*?NOv7tB-y%=oZpVWN4&cK{9;B7F7nlR+0fpTd+b;4cL}~1r%!kfqYtm$ z3x4OOw@~73U+@wW!V(Sj2^G_YzAhBt|hMo+bog&}; zMs0Q+F(=4ospXJUA=*4p^-@Z$kLoSQMoCP}^GtUMF=*k&!v3JvGK=iTo0|u8E+pk$ z7NlF|SdTiA}9z`hD&N?V1-jZNJQ% zwrg<4;DU-HmZp}ru}0IEx5c;7Tsk6(g)cW44J^`^F7+td*k-)5lm08=uomr%trI@@ zfcw)Qq_az!#<2eQ#A{RA9u^B*+9zJy;qGzgGcRvxF}|TG`A7273=)TRK(U$G}-qyrz%cUFBV84&{k1eP@+wrbjl+#*PkqtB5;Ur1Q&oFXRZ?w&x zN%uh>o6(b(uana|wu+e)|8i)?O-0h|>T9iUuD{bnW-Nh^@_f3re!iz|*u#i(^EqkZ zUtO$T?)yXLf>LleSo?J=KSJlIr;utD^k|LWDnwc4E=9o8>rwl9ZJdX_&z{KH6);{q zTF`3Jb}8~wnOFVg!UJ6!U(O4B{UUxbyrC}h?G)cPDOW1_w_m6|S$xiK*|L4w)e+`T z7H(rYziPylpSr*O>LK%y`dhzqXA;x5uKbxvwFSC03`!bqun(VpfegTs%+hLzo2KW- z+k1>9`T}uPXL9#xN&;YpH+yV&pX*k)#nju?MAzk#_Pg{9 zgfw<1P2VC2D1H{2zqUG4?f{G>PI=Samqbz>&#{>Q?Ad$pz3QM>z1ogp6GH${+01u! z_4Rah{rJIxK2teAq*Fa==yR@y+>3Bqs6W#vrvA?Qv+#x8^OxHuZ*E)>e!r@x5f$E; zmRC&DE>zc~%{--VcdL|AtexDYnR0I9o+I1$j#T8`K{RiCoLF8qTpX{dwNrZ;vs3L* z#J==x*J`5#%m1u6VqEi^WpYuiH#I%@#-W!ZrCYb2migu0A8R|vp*Ljf{+3cJ@g~}K z>vd-`mpm(9I)^*Y)6&VtoY$|ApX6Dj zynNFqI;-~2xD}Lh-)rZEfrgM-^^uGCh4<#T&ROCCpJIrOn12+e^ z$0JlT#^zq`Xm)Y0?6Mcdv^V!qyTqEaVjJhVisz!3hkb#L+r8Q1$~(wA6;EF`w_ba$ zns&HwpHQ*U74Dzc_sVW?;ALNbC$3;T5jbKlE=}0lgMdyJ!+huj5yrzEUu6Z z+R39u&WB?V#pXwifgMD|ybQaNHz(okvSw5+MWfC z;qhNUc?u*_mVg5)p&)QOK7>Og@$5kyn~Nmic^D*~OTr-8SdfFnV%a1d0mO00Sj-m? zOT~OBD_K!rdZmQoLQotcfoM-+5s?Hk8gdE56Ob$thlM1eIUt(H#i4QBNpH9u%3`57 zngvZKKbjQ=qC|qQ2^&hnDbBv0R0P%z{kg|CiY4Vi3eXzh3%Ej=(NJ8)AWJF~ z2MC2xRD{wgxKeW>!QqaR)8fIGKoYUaod1yZ%fOh)*5o3H;!h00;S-5VVR0snNLcGZ z?t~#oZ*qte&Ju)y&H#CQU5aClLBAtaS$z&ebC+sZN;chd+`Uplo|3jJ|EKTZ?phGe>d_?{C=nF zJ6+$zz&8nh&#v!ueG>!UB>X+Q{$q4$f4J;weZ}Me6Uf44^-4f&PvLRM<=0 z89<7-cfcLT8yq%WGo~jbsMLN{ z?2yfgoC0?k_XHjdsT){?07G9Dj|0jR Date: Sun, 23 Jun 2024 12:55:11 +0800 Subject: [PATCH 33/71] Use mixins to fix fabric CT so it works for steps and panels too --- .../model/fabric/FilteredCopycatModel.java | 43 ------------------- .../base/model/fabric/SimpleCopycatModel.java | 5 ++- .../mixin/copycat/base/CopycatModelMixin.java | 41 ++++++++++++++++++ .../resources/copycats-fabric.mixins.json | 1 + 4 files changed, 45 insertions(+), 45 deletions(-) delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java deleted file mode 100644 index b53136740..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.fabric; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; -import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.function.Supplier; - -/** - * A Fabric-specific class to implement canConnectTexturesToward and CT toggling logic - */ -public abstract class FilteredCopycatModel extends CopycatModel { - public FilteredCopycatModel(BakedModel originalModel) { - super(originalModel); - } - - @Override - protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { - if (state.getBlock() instanceof CopycatBlock copycatBlock) { - FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { - BlockEntity be = blockView.getBlockEntity(pos); - if (be instanceof CTCopycatBlockEntity ctbe) - if (!ctbe.isCTEnabled()) - return false; - return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); - }); - emitBlockQuadsFiltered(filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } else { - emitBlockQuadsFiltered(blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } - } - - protected abstract void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData); -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java index 36004f28b..603b036e7 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java @@ -2,6 +2,7 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.CopycatRenderContextFabric; +import com.simibubi.create.content.decoration.copycat.CopycatModel; import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -17,7 +18,7 @@ import static com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.assembleQuad; -public class SimpleCopycatModel extends FilteredCopycatModel { +public class SimpleCopycatModel extends CopycatModel { private final SimpleCopycatPart part; @@ -27,7 +28,7 @@ public SimpleCopycatModel(BakedModel originalModel, SimpleCopycatPart part) { } @Override - protected void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { + protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { BakedModel model = getModelOf(material); // Use a mesh to defer quad emission since quads cannot be emitted inside a transform diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java new file mode 100644 index 000000000..08d9aa9c7 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java @@ -0,0 +1,41 @@ +package com.copycatsplus.copycats.fabric.mixin.copycat.base; + +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatModel; +import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; + +import java.util.function.Supplier; + +@Mixin(CopycatModel.class) +public class CopycatModelMixin { + @WrapOperation( + method = "emitBlockQuads", + at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/decoration/copycat/CopycatModel;emitBlockQuadsInner(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Ljava/util/function/Supplier;Lnet/fabricmc/fabric/api/renderer/v1/render/RenderContext;Lnet/minecraft/world/level/block/state/BlockState;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$CullFaceRemovalData;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$OcclusionData;)V") + ) + private void fixCT(CopycatModel instance, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, @Coerce Object cullFaceRemovalData, @Coerce Object occlusionData, Operation original) { + if (state.getBlock() instanceof CopycatBlock copycatBlock) { + FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { + BlockEntity be = blockView.getBlockEntity(pos); + if (be instanceof CTCopycatBlockEntity ctbe) + if (!ctbe.isCTEnabled()) + return false; + return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); + }); + original.call(instance, filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } else { + original.call(instance, blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } + } +} diff --git a/fabric/src/main/resources/copycats-fabric.mixins.json b/fabric/src/main/resources/copycats-fabric.mixins.json index a3238e76d..48253d7b3 100644 --- a/fabric/src/main/resources/copycats-fabric.mixins.json +++ b/fabric/src/main/resources/copycats-fabric.mixins.json @@ -10,6 +10,7 @@ "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin" ], "client": [ + "copycat.base.CopycatModelMixin", "featuretoggle.SubMenuConfigScreenMixin" ], "injectors": { From 08fb53e439b90f28c7316fbbf3717772386bfd57 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 13:10:12 +0800 Subject: [PATCH 34/71] Fix face culling for slope layers --- .../content/copycat/slope_layer/CopycatSlopeLayerBlock.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java index 87c336cbd..65c1eea90 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope_layer/CopycatSlopeLayerBlock.java @@ -221,12 +221,14 @@ public boolean supportsExternalFaceHiding(BlockState state) { public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, Direction dir) { Direction facing = state.getValue(FACING); + Half half = state.getValue(HALF); int layers = state.getValue(LAYERS); if (state.is(this) == neighborState.is(this)) { Direction neighborFacing = neighborState.getValue(FACING); + Half neighborHalf = neighborState.getValue(HALF); int neighborLayers = neighborState.getValue(LAYERS); if (getMaterial(level, pos).skipRendering(getMaterial(level, pos.relative(dir)), dir.getOpposite())) { - return neighborFacing == facing && neighborLayers == layers || // cull the sides if two copycats of the same height are next to each other + return neighborFacing == facing && neighborHalf == half && neighborLayers == layers || // cull the sides if two copycats of the same height are next to each other // cull if both sides have a square block face (neighborFacing == facing.getOpposite() || neighborLayers == 8) && facing == dir.getOpposite() || (neighborFacing == facing.getOpposite() || layers == 8) && neighborFacing == dir || From df88dc0cfb4de47d29f37910518b597b3423639f Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 12:55:11 +0800 Subject: [PATCH 35/71] Use mixins to fix fabric CT so it works for steps and panels too --- .../model/fabric/FilteredCopycatModel.java | 43 ------------------- .../base/model/fabric/SimpleCopycatModel.java | 5 ++- .../mixin/copycat/base/CopycatModelMixin.java | 41 ++++++++++++++++++ .../resources/copycats-fabric.mixins.json | 1 + 4 files changed, 45 insertions(+), 45 deletions(-) delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java deleted file mode 100644 index b53136740..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/FilteredCopycatModel.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.copycatsplus.copycats.content.copycat.base.model.fabric; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; -import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; - -import java.util.function.Supplier; - -/** - * A Fabric-specific class to implement canConnectTexturesToward and CT toggling logic - */ -public abstract class FilteredCopycatModel extends CopycatModel { - public FilteredCopycatModel(BakedModel originalModel) { - super(originalModel); - } - - @Override - protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { - if (state.getBlock() instanceof CopycatBlock copycatBlock) { - FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { - BlockEntity be = blockView.getBlockEntity(pos); - if (be instanceof CTCopycatBlockEntity ctbe) - if (!ctbe.isCTEnabled()) - return false; - return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); - }); - emitBlockQuadsFiltered(filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } else { - emitBlockQuadsFiltered(blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } - } - - protected abstract void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData); -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java index 36004f28b..603b036e7 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java @@ -2,6 +2,7 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.CopycatRenderContextFabric; +import com.simibubi.create.content.decoration.copycat.CopycatModel; import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -17,7 +18,7 @@ import static com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.assembleQuad; -public class SimpleCopycatModel extends FilteredCopycatModel { +public class SimpleCopycatModel extends CopycatModel { private final SimpleCopycatPart part; @@ -27,7 +28,7 @@ public SimpleCopycatModel(BakedModel originalModel, SimpleCopycatPart part) { } @Override - protected void emitBlockQuadsFiltered(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { + protected void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { BakedModel model = getModelOf(material); // Use a mesh to defer quad emission since quads cannot be emitted inside a transform diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java new file mode 100644 index 000000000..08d9aa9c7 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java @@ -0,0 +1,41 @@ +package com.copycatsplus.copycats.fabric.mixin.copycat.base; + +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatModel; +import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; + +import java.util.function.Supplier; + +@Mixin(CopycatModel.class) +public class CopycatModelMixin { + @WrapOperation( + method = "emitBlockQuads", + at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/decoration/copycat/CopycatModel;emitBlockQuadsInner(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Ljava/util/function/Supplier;Lnet/fabricmc/fabric/api/renderer/v1/render/RenderContext;Lnet/minecraft/world/level/block/state/BlockState;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$CullFaceRemovalData;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$OcclusionData;)V") + ) + private void fixCT(CopycatModel instance, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, @Coerce Object cullFaceRemovalData, @Coerce Object occlusionData, Operation original) { + if (state.getBlock() instanceof CopycatBlock copycatBlock) { + FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { + BlockEntity be = blockView.getBlockEntity(pos); + if (be instanceof CTCopycatBlockEntity ctbe) + if (!ctbe.isCTEnabled()) + return false; + return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); + }); + original.call(instance, filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } else { + original.call(instance, blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } + } +} diff --git a/fabric/src/main/resources/copycats-fabric.mixins.json b/fabric/src/main/resources/copycats-fabric.mixins.json index a3238e76d..48253d7b3 100644 --- a/fabric/src/main/resources/copycats-fabric.mixins.json +++ b/fabric/src/main/resources/copycats-fabric.mixins.json @@ -10,6 +10,7 @@ "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin" ], "client": [ + "copycat.base.CopycatModelMixin", "featuretoggle.SubMenuConfigScreenMixin" ], "injectors": { From ee3610458fe7509bcb4916907f0cec8458b71f3f Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Sun, 23 Jun 2024 13:56:03 +0800 Subject: [PATCH 36/71] Bump version to 1.3.5 for tester version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9010ac223..1e8a8d7f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx3G #Mod archives_base_name=Copycats -mod_version=1.3.4 +mod_version=1.3.5 is_test_build=false maven_group=com.copycatsplus mod_authors=Lysine, Bennyboy1695, Redcat_XVIII From cf40a71aefd4ddf21c7dd40807c45d7114e5f760 Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Sun, 23 Jun 2024 14:31:08 +0100 Subject: [PATCH 37/71] Fans can now partially understand multistates --- .../base/multistate/AirCurrentMixin.java | 20 +++++++++++++++++++ .../resources/copycats-common.mixins.json | 1 + 2 files changed, 21 insertions(+) create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/AirCurrentMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/AirCurrentMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/AirCurrentMixin.java new file mode 100644 index 000000000..074ab2051 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/multistate/AirCurrentMixin.java @@ -0,0 +1,20 @@ +package com.copycatsplus.copycats.mixin.copycat.base.multistate; + +import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.kinetics.fan.AirCurrent; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(AirCurrent.class) +public class AirCurrentMixin { + + @Redirect(method = "getFlowLimit", at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/decoration/copycat/CopycatBlock;getMaterial(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;")) + private static BlockState copycats$getMultiStateMaterial(BlockGetter cbe, BlockPos reader) { + return cbe.getBlockState(reader).getBlock() instanceof MultiStateCopycatBlock ? MultiStateCopycatBlock.getMaterial(cbe, reader) : CopycatBlock.getMaterial(cbe, reader); + } +} diff --git a/common/src/main/resources/copycats-common.mixins.json b/common/src/main/resources/copycats-common.mixins.json index bd2f3a7b6..5d2890499 100644 --- a/common/src/main/resources/copycats-common.mixins.json +++ b/common/src/main/resources/copycats-common.mixins.json @@ -16,6 +16,7 @@ "copycat.base.CopycatBlockEntityMixin", "copycat.base.CopycatBlockMixin", "copycat.base.FilteredBlockAndTintGetterAccessor", + "copycat.base.multistate.AirCurrentMixin", "copycat.base.multistate.ContraptionMixin", "copycat.base.multistate.LevelChunkMixin", "copycat.button.ButtonBlockMixin", From d68fbbeb23ede10828c301ca304006695730ebd7 Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Mon, 24 Jun 2024 01:51:35 +0100 Subject: [PATCH 38/71] Remove data-fixers completely are they are useless for what we originally made them for Fix ct appearance check --- common/build.gradle | 4 - .../copycatsplus/copycats/CCDataFixers.java | 45 ---- .../copycatsplus/copycats/config/CCommon.java | 4 - .../multistate/MultiStateCopycatBlock.java | 2 +- .../datafixers/api/DataFixesInternals.java | 86 -------- .../api/DataFixesInternalsImpl.java | 84 ------- .../copycats/datafixers/api/EmptySchema.java | 51 ----- .../copycats/datafixers/api/FirstSchema.java | 48 ---- .../copycats/datafixers/api/LICENSE | 205 ------------------ .../api/NoOpDataFixesInternals.java | 58 ----- .../CopycatsBlockEntityConversionFixer.java | 43 ---- .../main/resources/architectury.common.json | 3 - .../src/main/resources/copycats.accesswidener | 2 - forge/build.gradle | 4 - .../copycats/forge/CopycatsImpl.java | 8 - 15 files changed, 1 insertion(+), 646 deletions(-) delete mode 100644 common/src/main/java/com/copycatsplus/copycats/CCDataFixers.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternals.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternalsImpl.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/EmptySchema.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/FirstSchema.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/LICENSE delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/api/NoOpDataFixesInternals.java delete mode 100644 common/src/main/java/com/copycatsplus/copycats/datafixers/fixers/CopycatsBlockEntityConversionFixer.java delete mode 100644 common/src/main/resources/architectury.common.json delete mode 100644 common/src/main/resources/copycats.accesswidener diff --git a/common/build.gradle b/common/build.gradle index 851717558..c7a6ba2d4 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -2,10 +2,6 @@ architectury { common(enabled_platforms.split(",")) } -loom { - accessWidenerPath = file("src/main/resources/copycats.accesswidener") -} - dependencies { // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies // Do NOT use other classes from fabric loader diff --git a/common/src/main/java/com/copycatsplus/copycats/CCDataFixers.java b/common/src/main/java/com/copycatsplus/copycats/CCDataFixers.java deleted file mode 100644 index 67c0d0455..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/CCDataFixers.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.copycatsplus.copycats; - -import com.copycatsplus.copycats.config.CCConfigs; -import com.copycatsplus.copycats.datafixers.api.DataFixesInternals; -import com.copycatsplus.copycats.datafixers.fixers.CopycatsBlockEntityConversionFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import net.minecraft.Util; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.util.datafix.schemas.NamespacedSchema; - -import java.util.Set; -import java.util.function.BiFunction; - -import static com.copycatsplus.copycats.datafixers.api.DataFixesInternals.BASE_SCHEMA; - -public class CCDataFixers { - private static final BiFunction SAME = Schema::new; - private static final BiFunction SAME_NAMESPACED = NamespacedSchema::new; - public static CopycatsBlockEntityConversionFixer fixer; - - public static void register() { - Copycats.LOGGER.info("Registering data fixers"); - - if (CCConfigs.safeGetter(CCConfigs.common().disableDataFixers::get, false).get()) { - Copycats.LOGGER.warn("Skipping Datafixer Registration due to it being disabled in the config."); - return; - } - - DataFixesInternals api = DataFixesInternals.get(); - - DataFixerBuilder builder = new DataFixerBuilder(Copycats.DATA_FIXER_VERSION); - addFixers(builder); - api.registerFixer(Copycats.DATA_FIXER_VERSION, builder.buildOptimized(Set.of(References.BLOCK_ENTITY), Util.backgroundExecutor())); - } - - private static void addFixers(DataFixerBuilder builder) { - builder.addSchema(0, BASE_SCHEMA); - - // Register a schema, and then the fixes to get *to* that schema - - Schema schemaV1 = builder.addSchema(1, SAME_NAMESPACED); - builder.addFixer(fixer = new CopycatsBlockEntityConversionFixer(schemaV1, "Replace block_entity id and transfer nbt data")); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java b/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java index cdcd3b10f..ca84fc306 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/CCommon.java @@ -15,8 +15,6 @@ public String getName() { return "common"; } - public final ConfigBool disableDataFixers = b(false, "disableDataFixers", Comments.dataFixers); - public final ConfigBool disableConversion = b(false, "disableConversion", Comments.multiStateConversion); public final CFeatures toggle = nested(0, CFeatures::new, Comments.toggle); @@ -27,8 +25,6 @@ public void register() { private static class Comments { static String toggle = "Enable/disable features. Values on server override clients"; - static String dataFixers = "Enables/Disables the data fixers. (Currently none available)"; - static String multiStateConversion = "Enables/Disables the conversion of placed copycats from the single material to the multi material(where applicable) block entity. Set this to false to enable conversion! (only happens on world load, so if changed while ingame you will need to load the world again)"; } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java index 299f5cb08..1607e7da7 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java @@ -359,7 +359,7 @@ public boolean allowCTAppearance(MultiStateCopycatBlock block, BlockState state, } MultiStateCopycatBlockEntity be = getBlockEntity(level, queryPos); if (be == null) return true; - return be.getMaterialItemStorage().getMaterialItem(property).enableCT(); + return be.getMaterialItemStorage().getMaterialItem(property) == null || be.getMaterialItemStorage().getMaterialItem(property).enableCT(); } public boolean isIgnoredConnectivitySide(String property, BlockAndTintGetter reader, BlockState state, Direction face, diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternals.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternals.java deleted file mode 100644 index a69d6efe5..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternals.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2022 QuiltMC - * Modified by the Steam 'n' Rails (Railways) team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.copycatsplus.copycats.datafixers.api; - -import com.copycatsplus.copycats.Copycats; -import com.mojang.datafixers.DataFixUtils; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import net.minecraft.SharedConstants; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.datafix.DataFixTypes; -import net.minecraft.util.datafix.DataFixers; -import org.jetbrains.annotations.*; - -import java.util.function.BiFunction; - -import static com.google.common.base.Preconditions.checkArgument; - -@ApiStatus.Internal -public abstract class DataFixesInternals { - - public static final BiFunction BASE_SCHEMA = (version, parent) -> { - checkArgument(version == 0, "version must be 0"); - checkArgument(parent == null, "parent must be null"); - return get().createBaseSchema(); - }; - - public record DataFixerEntry(DataFixer dataFixer, int currentVersion) {} - - @Contract(pure = true) - @Range(from = 0, to = Integer.MAX_VALUE) - public static int getModDataVersion(@NotNull CompoundTag compound) { - return compound.getInt("Railways_DataVersion"); - } - - private static DataFixesInternals instance; - - public static @NotNull DataFixesInternals get() { - if (instance == null) { - Schema latestVanillaSchema; - try { - latestVanillaSchema = DataFixers.getDataFixer() - .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())); - } catch (Exception e) { - latestVanillaSchema = null; - } - - if (latestVanillaSchema == null) { - Copycats.LOGGER.warn("[Copycats+ DFU] Failed to initialize! Either someone stopped DFU from initializing,"); - Copycats.LOGGER.warn("[Copycats+ DFU] or this Minecraft build is hosed."); - Copycats.LOGGER.warn("[Copycats+ DFU] Using no-op implementation."); - instance = new NoOpDataFixesInternals(); - } else { - instance = new DataFixesInternalsImpl(latestVanillaSchema); - } - } - - return instance; - } - - public abstract void registerFixer(@Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer); - - public abstract @Nullable DataFixerEntry getFixerEntry(); - - @Contract(value = "-> new", pure = true) - public abstract @NotNull Schema createBaseSchema(); - - public abstract @NotNull CompoundTag updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull CompoundTag compound); - - public abstract @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound); -} diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternalsImpl.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternalsImpl.java deleted file mode 100644 index 175f75b91..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/DataFixesInternalsImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2022 QuiltMC - * Modified by the Steam 'n' Rails (Railways) team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.copycatsplus.copycats.datafixers.api; - -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtOps; -import net.minecraft.util.datafix.DataFixTypes; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; - -@ApiStatus.Internal -public final class DataFixesInternalsImpl extends DataFixesInternals { - private final @NotNull Schema latestVanillaSchema; - - private DataFixerEntry dataFixer; - - public DataFixesInternalsImpl(@NotNull Schema latestVanillaSchema) { - this.latestVanillaSchema = latestVanillaSchema; - - this.dataFixer = null; - } - - @Override - public void registerFixer(@Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, - @NotNull DataFixer dataFixer) { - if (this.dataFixer != null) { - throw new IllegalArgumentException("Copycats+ already has a registered data fixer"); - } - - this.dataFixer = new DataFixerEntry(dataFixer, currentVersion); - } - - @Override - public @Nullable DataFixerEntry getFixerEntry() { - return dataFixer; - } - - @Override - public @NotNull Schema createBaseSchema() { - return new Schema(0, this.latestVanillaSchema); - } - - @Override - public @NotNull CompoundTag updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull CompoundTag compound) { - var current = new Dynamic<>(NbtOps.INSTANCE, compound); - - if (dataFixer != null) { - int modDataVersion = DataFixesInternals.getModDataVersion(compound); - current = dataFixer.dataFixer() - .update(dataFixTypes.type, - current, - modDataVersion, dataFixer.currentVersion()); - } - - return (CompoundTag) current.getValue(); - } - - @Override - public @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound) { - if (dataFixer != null) - compound.putInt("Copycats_DataVersion", dataFixer.currentVersion()); - - return compound; - } -} \ No newline at end of file diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/EmptySchema.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/EmptySchema.java deleted file mode 100644 index e261a3135..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/EmptySchema.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022 QuiltMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.copycatsplus.copycats.datafixers.api; - -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.datafixers.types.Type; -import com.mojang.datafixers.types.templates.TypeTemplate; -import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; -import org.jetbrains.annotations.Range; - -import java.util.Map; -import java.util.function.Supplier; - -/** - * Represents an empty {@link Schema}, having no parent and containing no type definitions. - */ -public final class EmptySchema extends FirstSchema { - /** - * Constructs an empty schema. - * - * @param versionKey the data version key - */ - public EmptySchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { - super(versionKey); - } - - // Ensure the schema stays empty. - @Override - public void registerType(boolean recursive, DSL.TypeReference type, Supplier template) { - throw new UnsupportedOperationException(); - } - - @Override - protected Map> buildTypes() { - return Object2ObjectMaps.emptyMap(); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/FirstSchema.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/FirstSchema.java deleted file mode 100644 index ed9758f52..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/FirstSchema.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2022 QuiltMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.copycatsplus.copycats.datafixers.api; - -import com.mojang.datafixers.schemas.Schema; -import com.mojang.datafixers.types.templates.TypeTemplate; -import org.jetbrains.annotations.Range; - -import java.util.Map; -import java.util.function.Supplier; - -public class FirstSchema extends Schema { - /** - * Creates a schema. - * @param versionKey the data version key - */ - public FirstSchema(@Range(from = 0, to = Integer.MAX_VALUE) int versionKey) { - super(versionKey, null); - } - - // all of these methods refer to this.parent without checking if its null - @Override - public void registerTypes(Schema schema, Map> entityTypes, - Map> blockEntityTypes) {} - - @Override - public Map> registerEntities(Schema schema) { - return Map.of(); - } - - @Override - public Map> registerBlockEntities(Schema schema) { - return Map.of(); - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/LICENSE b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/LICENSE deleted file mode 100644 index 2b9aceae6..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/LICENSE +++ /dev/null @@ -1,205 +0,0 @@ -Certain portions of the datafixer are taken from the -Quilt Standard Library (https://github.com/QuiltMC/quilt-standard-libraries), -and as such are licensed under the following license: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/NoOpDataFixesInternals.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/api/NoOpDataFixesInternals.java deleted file mode 100644 index 31601efc9..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/api/NoOpDataFixesInternals.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2022 QuiltMC - * Modified by the Steam 'n' Rails (Railways) team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.copycatsplus.copycats.datafixers.api; - - -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.schemas.Schema; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.datafix.DataFixTypes; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Range; - -public class NoOpDataFixesInternals extends DataFixesInternals { - - private final Schema schema; - - public NoOpDataFixesInternals() { - schema = new EmptySchema(0); - } - - @Override - public void registerFixer(@Range(from = 0, to = Integer.MAX_VALUE) int currentVersion, @NotNull DataFixer dataFixer) {} - - @Override - public @Nullable DataFixerEntry getFixerEntry() { - return null; - } - - @Override - public @NotNull Schema createBaseSchema() { - return schema; - } - - @Override - public @NotNull CompoundTag updateWithAllFixers(@NotNull DataFixTypes dataFixTypes, @NotNull CompoundTag compound) { - return compound.copy(); - } - - @Override - public @NotNull CompoundTag addModDataVersions(@NotNull CompoundTag compound) { - return compound; - } -} diff --git a/common/src/main/java/com/copycatsplus/copycats/datafixers/fixers/CopycatsBlockEntityConversionFixer.java b/common/src/main/java/com/copycatsplus/copycats/datafixers/fixers/CopycatsBlockEntityConversionFixer.java deleted file mode 100644 index 4c21baf7e..000000000 --- a/common/src/main/java/com/copycatsplus/copycats/datafixers/fixers/CopycatsBlockEntityConversionFixer.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.copycatsplus.copycats.datafixers.fixers; - -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DataFix; -import com.mojang.datafixers.TypeRewriteRule; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.util.datafix.fixes.References; - -import java.util.Optional; - -public class CopycatsBlockEntityConversionFixer extends DataFix { - - private String name; - public CopycatsBlockEntityConversionFixer(Schema outputSchema, String name) { - super(outputSchema, false); - this.name = name; - } - - @Override - protected TypeRewriteRule makeRule() { - return this.fixTypeEverywhereTyped(this.name + " for block_entity", this.getInputSchema().getType(References.BLOCK_ENTITY), typed -> typed.update(DSL.remainderFinder(), dynamic -> { - Optional optional = dynamic.get("id").asString().result(); - Optional name = dynamic.get("Name").asString().result(); - if (optional.isPresent() && optional.get().equalsIgnoreCase("create:copycat") - && name.isPresent() && name.get().startsWith("copycats:")) { - - Dynamic material = dynamic.get("Material").orElseEmptyMap(); - Dynamic item = dynamic.get("Item").orElseEmptyMap(); - - Dynamic material_data = dynamic.get("material_data").orElseEmptyMap(); - Dynamic placeholder = material_data.get("placeholder").orElseEmptyMap(); - placeholder.set("material", material); - placeholder.set("item", item); - - dynamic = dynamic.set("material_data", material_data); - dynamic = dynamic.set("id", dynamic.createString("copycats:multistate_copycat")); - return dynamic; - } - return dynamic; - })); - } -} diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json deleted file mode 100644 index a679703a1..000000000 --- a/common/src/main/resources/architectury.common.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "accessWidener": "copycats.accesswidener" -} \ No newline at end of file diff --git a/common/src/main/resources/copycats.accesswidener b/common/src/main/resources/copycats.accesswidener deleted file mode 100644 index 5903bdfdc..000000000 --- a/common/src/main/resources/copycats.accesswidener +++ /dev/null @@ -1,2 +0,0 @@ -accessWidener v2 named -accessible field net/minecraft/util/datafix/DataFixTypes type Lcom/mojang/datafixers/DSL$TypeReference; \ No newline at end of file diff --git a/forge/build.gradle b/forge/build.gradle index c9b0cd150..1d8b2a455 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -11,13 +11,9 @@ if (file("./../secrets.properties").exists()) { } loom { - - accessWidenerPath = project(":common").loom.accessWidenerPath forge { mixinConfig "copycats-common.mixins.json" mixinConfig "copycats-forge.mixins.json" - convertAccessWideners = true - extraAccessWideners.add(loom.accessWidenerPath.get().asFile.name) } runs { diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/CopycatsImpl.java b/forge/src/main/java/com/copycatsplus/copycats/forge/CopycatsImpl.java index f85e3f425..5e5bcd2f9 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/CopycatsImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/CopycatsImpl.java @@ -1,20 +1,12 @@ package com.copycatsplus.copycats.forge; -import com.copycatsplus.copycats.CCDataFixers; import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.CopycatsClient; -import com.copycatsplus.copycats.datafixers.api.DataFixesInternals; -import com.copycatsplus.copycats.datafixers.fixers.CopycatsBlockEntityConversionFixer; import com.copycatsplus.copycats.datagen.forge.CCDatagenImpl; import com.copycatsplus.copycats.datagen.recipes.forge.CCCraftingConditions; import com.copycatsplus.copycats.multiloader.LogicalSidedProvider; import com.copycatsplus.copycats.multiloader.Platform; -import net.minecraft.client.telemetry.events.WorldLoadEvent; -import net.minecraft.util.datafix.DataFixTypes; -import net.minecraft.util.datafix.fixes.References; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.level.ChunkEvent; -import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; From 8df5a7a7b7e46bc137ad4600ea39c3cf4dc517d8 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 17:33:04 +0800 Subject: [PATCH 39/71] Initial implementation of copycat shaft Todo: - Provide block color - Implement block events - Implement CT - Implement GPU instancing --- .../copycats/CCBlockEntityTypes.java | 16 ++ .../com/copycatsplus/copycats/CCBlocks.java | 22 +- .../copycats/CCBuilderTransformers.java | 6 + .../copycatsplus/copycats/CCCreativeTabs.java | 3 +- .../copycatsplus/copycats/CopycatsClient.java | 6 + .../functional/IFunctionalCopycatBlock.java | 261 ++++++++++++++++++ .../IFunctionalCopycatBlockEntity.java | 96 +++++++ .../FunctionalCopycatRenderHelper.java | 33 +++ .../IFunctionalCopycatBlockRenderer.java | 12 + .../functional/KineticCopycatRenderData.java | 6 + .../copycat/shaft/CopycatShaftBlock.java | 87 ++++++ .../shaft/CopycatShaftBlockEntity.java | 65 +++++ .../copycat/shaft/CopycatShaftModel.java | 50 ++++ .../copycat/shaft/CopycatShaftRenderer.java | 20 ++ .../datagen/recipes/CCStandardRecipes.java | 9 + .../mixin/CopycatBlockEntityAccessor.java | 15 + .../resources/copycats-common.mixins.json | 1 + .../fabric/CCBuilderTransformersImpl.java | 16 ++ .../copycats/blockstates/copycat_shaft.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../copycats/models/item/copycat_shaft.json | 3 + .../misc/stonecutting/copycat_shaft.json | 33 +++ .../loot_tables/blocks/copycat_shaft.json | 21 ++ .../recipes/stonecutting/copycat_shaft.json | 8 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../forge/BakedModelWithDataBuilder.java | 62 +++++ .../FunctionalCopycatRenderHelperImpl.java | 46 +++ .../forge/CopycatShaftBlockEntityForge.java | 32 +++ .../shaft/forge/CopycatShaftModelForge.java | 46 +++ .../forge/CCBlockEntityTypesImpl.java | 7 + .../copycats/forge/CCBlocksImpl.java | 9 + .../forge/CCBuilderTransformersImpl.java | 18 ++ 34 files changed, 1019 insertions(+), 5 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockRenderer.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftModel.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftRenderer.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/CopycatBlockEntityAccessor.java create mode 100644 forge/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json create mode 100644 forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json create mode 100644 forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json create mode 100644 forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json create mode 100644 forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java index 81b6c5e1b..8ea33ea58 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java @@ -2,7 +2,11 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.ladder.CopycatLadderMultiStateBlockEntity; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftRenderer; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer; import com.tterrag.registrate.builders.BlockEntityBuilder; import com.tterrag.registrate.util.entry.BlockEntityEntry; import dev.architectury.injectables.annotations.ExpectPlatform; @@ -52,6 +56,13 @@ public class CCBlockEntityTypes { .validBlocks(/*CCBlocks.COPYCAT_LADDER*/) .register(); + public static final BlockEntityEntry COPYCAT_SHAFT = + REGISTRATE.blockEntity("copycat_shaft", getPlatformShaft()) + .instance(() -> BracketedKineticBlockEntityInstance::new, false) + .validBlocks(CCBlocks.COPYCAT_SHAFT) + .renderer(() -> CopycatShaftRenderer::new) + .register(); + @ExpectPlatform public static BlockEntityBuilder.BlockEntityFactory getPlatformMultiState() { throw new AssertionError("This shouldn't appear"); @@ -62,6 +73,11 @@ public static BlockEntityBuilder.BlockEntityFactory getPlatformShaft() { + throw new AssertionError("This shouldn't appear"); + } + public static void register() { } } diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index cc2a8a338..cad0212cd 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -35,6 +35,8 @@ import com.copycatsplus.copycats.content.copycat.layer.CopycatLayerBlock; import com.copycatsplus.copycats.content.copycat.layer.CopycatLayerModel; import com.copycatsplus.copycats.content.copycat.pressure_plate.*; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftModel; import com.copycatsplus.copycats.content.copycat.slab.CopycatMultiSlabModel; import com.copycatsplus.copycats.content.copycat.slab.CopycatSlabBlock; import com.copycatsplus.copycats.content.copycat.slice.CopycatSliceBlock; @@ -63,13 +65,14 @@ import com.copycatsplus.copycats.content.copycat.wall.WrappedWallBlock; import com.copycatsplus.copycats.datagen.CCLootGen; import com.simibubi.create.AllTags; -import com.simibubi.create.foundation.data.BuilderTransformers; -import com.simibubi.create.foundation.data.CreateRegistrate; +import com.simibubi.create.content.kinetics.BlockStressDefaults; +import com.simibubi.create.foundation.data.*; import com.tterrag.registrate.AbstractRegistrate; import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.RegistrateBlockstateProvider; import com.tterrag.registrate.util.entry.BlockEntry; import com.tterrag.registrate.util.entry.RegistryEntry; +import net.minecraft.client.resources.model.BakedModel; import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.tags.BlockTags; @@ -82,6 +85,7 @@ import javax.annotation.Nullable; import java.util.HashSet; + import java.util.Set; import java.util.stream.Collectors; @@ -486,6 +490,20 @@ public class CCBlocks { .transform(customItemModel("copycat_base", "slope")) .register(); + public static final BlockEntry COPYCAT_SHAFT = REGISTRATE.block("copycat_shaft", CopycatShaftBlock::new) + .transform(CCBuilderTransformers.functionalCopycat()) + .transform(FeatureToggle.register()) + .transform(BlockStressDefaults.setNoImpact()) + .onRegister(CreateRegistrate.blockModel(() -> model -> getShaftModel(model, SimpleCopycatPart.create(model, new CopycatShaftModel())))) + .item() + .transform(customItemModel("copycat_base", "beam")) + .register(); + + @ExpectPlatform + public static BakedModel getShaftModel(BakedModel original, BakedModel copycat) { + throw new AssertionError(); + } + public static @Nullable BlockEntry COPYCAT_TEST_BLOCK; @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBuilderTransformers.java b/common/src/main/java/com/copycatsplus/copycats/CCBuilderTransformers.java index 8ec89166f..ff553132a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBuilderTransformers.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBuilderTransformers.java @@ -2,6 +2,7 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; import com.tterrag.registrate.builders.BlockBuilder; +import net.minecraft.world.level.block.Block; import com.tterrag.registrate.util.nullness.NonNullUnaryOperator; import dev.architectury.injectables.annotations.ExpectPlatform; @@ -16,4 +17,9 @@ public static NonNullUnaryOperator NonNullUnaryOperator> testBlockMultiCopycat() { throw new AssertionError("Shouldn't appear"); } + + @ExpectPlatform + public static NonNullUnaryOperator> functionalCopycat() { + throw new AssertionError("Shouldn't appear"); + } } diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index 9e8fb1f21..653a0cfe6 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -39,7 +39,8 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_WALL, CCBlocks.COPYCAT_WOODEN_BUTTON, CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, - CCBlocks.COPYCAT_SLOPE + CCBlocks.COPYCAT_SLOPE, + CCBlocks.COPYCAT_SHAFT ); @ExpectPlatform diff --git a/common/src/main/java/com/copycatsplus/copycats/CopycatsClient.java b/common/src/main/java/com/copycatsplus/copycats/CopycatsClient.java index bcb16432a..df72c2f25 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CopycatsClient.java +++ b/common/src/main/java/com/copycatsplus/copycats/CopycatsClient.java @@ -1,13 +1,19 @@ package com.copycatsplus.copycats; +import com.copycatsplus.copycats.content.copycat.base.model.functional.FunctionalCopycatRenderHelper; +import com.copycatsplus.copycats.content.copycat.base.model.functional.IFunctionalCopycatBlockRenderer; import com.copycatsplus.copycats.multiloader.LogicalSidedProvider; import com.copycatsplus.copycats.network.CCPackets; +import com.simibubi.create.foundation.render.SuperByteBufferCache; import net.minecraft.client.Minecraft; public class CopycatsClient { + public static final SuperByteBufferCache BUFFER_CACHE = new SuperByteBufferCache(); + public static void init() { LogicalSidedProvider.setClient(Minecraft::getInstance); CCPackets.PACKETS.registerS2CListener(); + BUFFER_CACHE.registerCompartment(FunctionalCopycatRenderHelper.KINETIC_COPYCAT, 60); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java new file mode 100644 index 000000000..d7cd1e187 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -0,0 +1,261 @@ +package com.copycatsplus.copycats.content.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllTags; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.content.equipment.wrench.IWrenchable; +import com.simibubi.create.foundation.placement.IPlacementHelper; +import com.simibubi.create.foundation.placement.PlacementHelpers; +import com.simibubi.create.foundation.utility.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.GrassColor; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.StairBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import javax.annotation.Nullable; + +/** + * Indicates that a block functions as a copycat but is not a subclass of {@link CopycatBlock}. + */ +public interface IFunctionalCopycatBlock extends IWrenchable { + + @Nullable + default IFunctionalCopycatBlockEntity getCopycatBlockEntity(BlockGetter worldIn, BlockPos pos) { + BlockEntity blockEntity = worldIn.getBlockEntity(pos); + + if (blockEntity == null) + return null; + if (!(blockEntity instanceof IFunctionalCopycatBlockEntity functionalCopycatBlockEntity)) + return null; + + return functionalCopycatBlockEntity; + } + + @Override + default InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { + onWrenched(state, context); + return IWrenchable.super.onSneakWrenched(state, context); + } + + @Override + default InteractionResult onWrenched(BlockState state, UseOnContext context) { + IFunctionalCopycatBlockEntity ufte = getCopycatBlockEntity(context.getLevel(), context.getClickedPos()); + if (ufte == null) + return InteractionResult.PASS; + ItemStack consumedItem = ufte.getConsumedItem(); + if (!ufte.hasCustomMaterial()) + return InteractionResult.PASS; + Player player = context.getPlayer(); + if (!player.isCreative()) + player.getInventory() + .placeItemBackInInventory(consumedItem); + context.getLevel() + .levelEvent(2001, context.getClickedPos(), Block.getId(ufte.getBlockState())); + ufte.setMaterial(AllBlocks.COPYCAT_BASE.getDefaultState()); + ufte.setConsumedItem(ItemStack.EMPTY); + return InteractionResult.SUCCESS; + } + + @Nullable + default BlockState getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack item, Direction face) { + if (!(item.getItem() instanceof BlockItem bi)) + return null; + + Block block = bi.getBlock(); + if (block instanceof CopycatBlock) + return null; + + BlockState appliedState = block.defaultBlockState(); + boolean hardCodedAllow = isAcceptedRegardless(appliedState); + + if (!AllTags.AllBlockTags.COPYCAT_ALLOW.matches(block) && !hardCodedAllow) { + + if (AllTags.AllBlockTags.COPYCAT_DENY.matches(block)) + return null; + if (block instanceof EntityBlock) + return null; + if (block instanceof StairBlock) + return null; + + if (pLevel != null) { + VoxelShape shape = appliedState.getShape(pLevel, pPos); + if (shape.isEmpty() || !shape.bounds() + .equals(Shapes.block() + .bounds())) + return null; + + VoxelShape collisionShape = appliedState.getCollisionShape(pLevel, pPos); + if (collisionShape.isEmpty()) + return null; + } + } + + if (face != null) { + Direction.Axis axis = face.getAxis(); + + if (appliedState.hasProperty(BlockStateProperties.FACING)) + appliedState = appliedState.setValue(BlockStateProperties.FACING, face); + if (appliedState.hasProperty(BlockStateProperties.HORIZONTAL_FACING) && axis != Direction.Axis.Y) + appliedState = appliedState.setValue(BlockStateProperties.HORIZONTAL_FACING, face); + if (appliedState.hasProperty(BlockStateProperties.AXIS)) + appliedState = appliedState.setValue(BlockStateProperties.AXIS, axis); + if (appliedState.hasProperty(BlockStateProperties.HORIZONTAL_AXIS) && axis != Direction.Axis.Y) + appliedState = appliedState.setValue(BlockStateProperties.HORIZONTAL_AXIS, axis); + } + + return appliedState; + } + + default boolean isAcceptedRegardless(BlockState material) { + return false; + } + + default BlockState prepareMaterial(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer, + InteractionHand pHand, BlockHitResult pHit, BlockState material) { + return material; + } + + default InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) { + if (player.isShiftKeyDown() && player.getItemInHand(hand).equals(ItemStack.EMPTY)) { + IFunctionalCopycatBlockEntity be = getCopycatBlockEntity(world, pos); + be.setCTEnabled(!be.isCTEnabled()); + be.callRedraw(); + return InteractionResult.SUCCESS; + } + + if (player == null || player != null && !player.mayBuild() && !player.isSpectator()) + return InteractionResult.PASS; + + Direction face = ray.getDirection(); + ItemStack itemInHand = player.getItemInHand(hand); + BlockState materialIn = getAcceptedBlockState(world, pos, itemInHand, face); + + if (materialIn != null) + materialIn = prepareMaterial(world, pos, state, player, hand, ray, materialIn); + if (materialIn == null) + return InteractionResult.PASS; + + BlockState material = materialIn; + IFunctionalCopycatBlockEntity ufte = getCopycatBlockEntity(world, pos); + if (ufte == null) + return InteractionResult.PASS; + if (ufte.getMaterial() + .is(material.getBlock())) { + if (!ufte.cycleMaterial()) + return InteractionResult.PASS; + ufte.getLevel() + .playSound(null, ufte.getBlockPos(), SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .75f, + .95f); + return InteractionResult.SUCCESS; + } + if (ufte.hasCustomMaterial()) + return InteractionResult.PASS; + if (world.isClientSide()) + return InteractionResult.SUCCESS; + + ufte.setMaterial(material); + ufte.setConsumedItem(itemInHand); + ufte.getLevel() + .playSound(null, ufte.getBlockPos(), material.getSoundType() + .getPlaceSound(), SoundSource.BLOCKS, 1, .75f); + + if (player.isCreative()) + return InteractionResult.SUCCESS; + + itemInHand.shrink(1); + if (itemInHand.isEmpty()) + player.setItemInHand(hand, ItemStack.EMPTY); + return InteractionResult.SUCCESS; + } + + default void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + if (placer == null) + return; + ItemStack offhandItem = placer.getItemInHand(InteractionHand.OFF_HAND); + BlockState appliedState = + getAcceptedBlockState(worldIn, pos, offhandItem, Direction.orderedByNearest(placer)[0]); + + if (appliedState == null) + return; + IFunctionalCopycatBlockEntity ufte = getCopycatBlockEntity(worldIn, pos); + if (ufte == null) + return; + if (ufte.hasCustomMaterial()) + return; + + ufte.setMaterial(appliedState); + ufte.setConsumedItem(offhandItem); + + if (placer instanceof Player player && player.isCreative()) + return; + offhandItem.shrink(1); + if (offhandItem.isEmpty()) + placer.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY); + } + + default void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { + if (!state.hasBlockEntity() || state.getBlock() == newState.getBlock()) + return; + if (!isMoving) { + IFunctionalCopycatBlockEntity ufte = getCopycatBlockEntity(world, pos); + if (ufte != null) + Block.popResource(world, pos, ufte.getConsumedItem()); + } + world.removeBlockEntity(pos); + } + + default void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { + if (player.isCreative()) { + IFunctionalCopycatBlockEntity ufte = getCopycatBlockEntity(level, pos); + if (ufte != null) ufte.setConsumedItem(ItemStack.EMPTY); + } + } + + static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) { + if (reader.getBlockEntity(targetPos) instanceof IFunctionalCopycatBlockEntity cbe) + return cbe.getMaterial(); + return Blocks.AIR.defaultBlockState(); + } + + static BlockColor wrappedColor() { + return new WrappedBlockColor(); + } + + static class WrappedBlockColor implements BlockColor { + + @Override + public int getColor(BlockState pState, @Nullable BlockAndTintGetter pLevel, @Nullable BlockPos pPos, + int pTintIndex) { + if (pLevel == null || pPos == null) + return GrassColor.get(0.5D, 1.0D); + return Minecraft.getInstance() + .getBlockColors() + .getColor(getMaterial(pLevel, pPos), pLevel, pPos, pTintIndex); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java new file mode 100644 index 000000000..629dde1f8 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java @@ -0,0 +1,96 @@ +package com.copycatsplus.copycats.content.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.copycatsplus.copycats.mixin.CopycatBlockEntityAccessor; +import com.simibubi.create.content.contraptions.ITransformableBlockEntity; +import com.simibubi.create.content.contraptions.StructureTransform; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement; +import com.simibubi.create.content.schematics.requirement.ItemRequirement; +import com.simibubi.create.foundation.utility.IPartialSafeNBT; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +public interface IFunctionalCopycatBlockEntity extends CTCopycatBlockEntity, ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT { + CopycatBlockEntity getCopycatBlockEntity(); + + default Level getLevel() { + return getCopycatBlockEntity().getLevel(); + } + + default BlockPos getBlockPos() { + return getCopycatBlockEntity().getBlockPos(); + } + + default BlockState getBlockState() { + return getCopycatBlockEntity().getBlockState(); + } + + default void setLevel(Level level) { + getCopycatBlockEntity().setLevel(level); + } + + default BlockState getMaterial() { + return getCopycatBlockEntity().getMaterial(); + } + + default boolean hasCustomMaterial() { + return getCopycatBlockEntity().hasCustomMaterial(); + } + + default void setMaterial(BlockState material) { + getCopycatBlockEntity().setMaterial(material); + } + + default boolean cycleMaterial() { + return getCopycatBlockEntity().cycleMaterial(); + } + + default ItemStack getConsumedItem() { + return getCopycatBlockEntity().getConsumedItem(); + } + + default void setConsumedItem(ItemStack consumedItem) { + getCopycatBlockEntity().setConsumedItem(consumedItem); + } + + @Override + default ItemRequirement getRequiredItems(BlockState state) { + return getCopycatBlockEntity().getRequiredItems(state); + } + + @Override + default void transform(StructureTransform transform) { + getCopycatBlockEntity().transform(transform); + } + + default void read(CompoundTag compound, boolean clientPacket) { + ((CopycatBlockEntityAccessor) getCopycatBlockEntity()).callRead(compound, clientPacket); + } + + default void writeSafe(CompoundTag tag) { + getCopycatBlockEntity().writeSafe(tag); + } + + default void write(CompoundTag compound, boolean clientPacket) { + ((CopycatBlockEntityAccessor) getCopycatBlockEntity()).callWrite(compound, clientPacket); + } + + @Override + default boolean isCTEnabled() { + return ((CTCopycatBlockEntity) getCopycatBlockEntity()).isCTEnabled(); + } + + @Override + default void setCTEnabled(boolean value) { + ((CTCopycatBlockEntity) getCopycatBlockEntity()).setCTEnabled(value); + } + + @Override + default void callRedraw() { + ((CTCopycatBlockEntity) getCopycatBlockEntity()).callRedraw(); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java new file mode 100644 index 000000000..1e4c97591 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java @@ -0,0 +1,33 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional; + +import com.copycatsplus.copycats.CopycatsClient; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.SuperByteBufferCache; +import dev.architectury.injectables.annotations.ExpectPlatform; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.resources.model.BakedModel; + +public class FunctionalCopycatRenderHelper { + public static final SuperByteBufferCache.Compartment KINETIC_COPYCAT = new SuperByteBufferCache.Compartment<>(); + + public static SuperByteBuffer copycatRender(IFunctionalCopycatBlockEntity be) { + BlockRenderDispatcher dispatcher = Minecraft.getInstance() + .getBlockRenderer(); + return copycatRender(dispatcher.getBlockModel(be.getBlockState()), be, new PoseStack()); + } + + public static SuperByteBuffer getBuffer(IFunctionalCopycatBlockEntity be) { + return CopycatsClient.BUFFER_CACHE.get(KINETIC_COPYCAT, + new KineticCopycatRenderData(be.getBlockState(), be.getMaterial(), be.isCTEnabled()), + () -> copycatRender(be) + ); + } + + @ExpectPlatform + public static SuperByteBuffer copycatRender(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { + return null; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockRenderer.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockRenderer.java new file mode 100644 index 000000000..abba11496 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockRenderer.java @@ -0,0 +1,12 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import net.minecraft.world.level.block.state.BlockState; + +public interface IFunctionalCopycatBlockRenderer { + + default SuperByteBuffer getRotatedModel(IFunctionalCopycatBlockEntity be, BlockState state) { + return FunctionalCopycatRenderHelper.getBuffer(be); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java new file mode 100644 index 000000000..83d02d1c7 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java @@ -0,0 +1,6 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional; + +import net.minecraft.world.level.block.state.BlockState; + +public record KineticCopycatRenderData(BlockState state, BlockState material, boolean enableCT) { +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java new file mode 100644 index 000000000..c08a793a8 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java @@ -0,0 +1,87 @@ +package com.copycatsplus.copycats.content.copycat.shaft; + +import com.copycatsplus.copycats.CCBlockEntityTypes; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.simibubi.create.content.kinetics.base.KineticBlockEntity; +import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; +import com.simibubi.create.foundation.placement.IPlacementHelper; +import com.simibubi.create.foundation.placement.PlacementHelpers; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public class CopycatShaftBlock extends ShaftBlock implements IFunctionalCopycatBlock { + + public CopycatShaftBlock(Properties properties) { + super(properties); + } + + @Override + public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { + InteractionResult result = super.onSneakWrenched(state, context); + if (result.consumesAction()) { + return result; + } + return IFunctionalCopycatBlock.super.onSneakWrenched(state, context); + } + + @Override + public InteractionResult onWrenched(BlockState state, UseOnContext context) { + InteractionResult result = super.onWrenched(state, context); + if (result.consumesAction()) { + return result; + } + return IFunctionalCopycatBlock.super.onWrenched(state, context); + } + + @Override + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) { + InteractionResult result = super.use(state, world, pos, player, hand, ray); + if (result.consumesAction()) { + return result; + } + if (!player.isShiftKeyDown() && player.mayBuild()) { + ItemStack heldItem = player.getItemInHand(hand); + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem)) { + placementHelper.getOffset(player, world, state, pos, ray) + .placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); + return InteractionResult.SUCCESS; + } + } + + return IFunctionalCopycatBlock.super.use(state, world, pos, player, hand, ray); + } + + @Override + public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + super.setPlacedBy(worldIn, pos, state, placer, stack); + IFunctionalCopycatBlock.super.setPlacedBy(worldIn, pos, state, placer, stack); + } + + @Override + public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { + super.onRemove(state, world, pos, newState, isMoving); + IFunctionalCopycatBlock.super.onRemove(state, world, pos, newState, isMoving); + } + + @Override + public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { + super.playerWillDestroy(level, pos, state, player); + IFunctionalCopycatBlock.super.playerWillDestroy(level, pos, state, player); + } + + @Override + public BlockEntityType getBlockEntityType() { + return CCBlockEntityTypes.COPYCAT_SHAFT.get(); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java new file mode 100644 index 000000000..2d5e0e7e9 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java @@ -0,0 +1,65 @@ +package com.copycatsplus.copycats.content.copycat.shaft; + +import com.copycatsplus.copycats.CCBlockEntityTypes; +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.mixin.CopycatBlockEntityAccessor; +import com.simibubi.create.CreateClient; +import com.simibubi.create.content.contraptions.ITransformableBlockEntity; +import com.simibubi.create.content.contraptions.StructureTransform; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; +import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement; +import com.simibubi.create.content.schematics.requirement.ItemRequirement; +import com.simibubi.create.foundation.utility.IPartialSafeNBT; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class CopycatShaftBlockEntity extends BracketedKineticBlockEntity implements IFunctionalCopycatBlockEntity { + + protected CopycatBlockEntity copycatBlockEntity; + + public CopycatShaftBlockEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + copycatBlockEntity = new CopycatBlockEntity(CCBlockEntityTypes.COPYCAT.get(), pos, state); + } + + @Override + public CopycatBlockEntity getCopycatBlockEntity() { + return copycatBlockEntity; + } + + @Override + public void setLevel(Level level) { + super.setLevel(level); + IFunctionalCopycatBlockEntity.super.setLevel(level); + } + + @Override + public void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + IFunctionalCopycatBlockEntity.super.read(compound, clientPacket); + } + + @Override + public void writeSafe(CompoundTag tag) { + IFunctionalCopycatBlockEntity.super.writeSafe(tag); + super.writeSafe(tag); + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + super.write(compound, clientPacket); + IFunctionalCopycatBlockEntity.super.write(compound, clientPacket); + } + + @Override + public void callRedraw() { + IFunctionalCopycatBlockEntity.super.callRedraw(); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftModel.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftModel.java new file mode 100644 index 000000000..53cd7c81b --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftModel.java @@ -0,0 +1,50 @@ +package com.copycatsplus.copycats.content.copycat.shaft; + +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.base.model.assembly.GlobalTransform; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.world.level.block.state.BlockState; + +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler.*; +import static com.copycatsplus.copycats.content.copycat.base.model.assembly.MutableCullFace.*; +import static com.copycatsplus.copycats.content.copycat.half_panel.CopycatHalfPanelBlock.FACING; +import static com.copycatsplus.copycats.content.copycat.half_panel.CopycatHalfPanelBlock.OFFSET; + +public class CopycatShaftModel implements SimpleCopycatPart { + + @Override + public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { + Axis axis = state.getValue(CopycatShaftBlock.AXIS); + + GlobalTransform transform = t -> t.rotateY(axis == Axis.X ? 90 : 0).rotateX(axis == Axis.Y ? 90 : 0); + assemblePiece( + context, + transform, + vec3(6, 6, 0), + aabb(2, 2, 16).move(0, 0, 0), + cull(UP | EAST) + ); + assemblePiece( + context, + transform, + vec3(8, 6, 0), + aabb(2, 2, 16).move(14, 0, 0), + cull(UP | WEST) + ); + assemblePiece( + context, + transform, + vec3(6, 8, 0), + aabb(2, 2, 16).move(0, 14, 0), + cull(DOWN | EAST) + ); + assemblePiece( + context, + transform, + vec3(8, 8, 0), + aabb(2, 2, 16).move(14, 14, 0), + cull(DOWN | WEST) + ); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftRenderer.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftRenderer.java new file mode 100644 index 000000000..0267517e0 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftRenderer.java @@ -0,0 +1,20 @@ +package com.copycatsplus.copycats.content.copycat.shaft; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.model.functional.IFunctionalCopycatBlockRenderer; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.world.level.block.state.BlockState; + +public class CopycatShaftRenderer extends BracketedKineticBlockEntityRenderer implements IFunctionalCopycatBlockRenderer { + public CopycatShaftRenderer(BlockEntityRendererProvider.Context context) { + super(context); + } + + @Override + protected SuperByteBuffer getRotatedModel(BracketedKineticBlockEntity be, BlockState state) { + return IFunctionalCopycatBlockRenderer.super.getRotatedModel((IFunctionalCopycatBlockEntity) be, state); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java index c425a71e0..0543dc140 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java @@ -3,7 +3,10 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCItems; import com.copycatsplus.copycats.CCTags; +import com.copycatsplus.copycats.content.copycat.base.ICopycatWithWrappedBlock; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; import com.copycatsplus.copycats.datagen.recipes.gen.CopycatsRecipeProvider; import com.copycatsplus.copycats.datagen.recipes.gen.GeneratedRecipeBuilder; import com.copycatsplus.copycats.multiloader.Platform; @@ -171,6 +174,8 @@ public class CCStandardRecipes extends CopycatsRecipeProvider { GeneratedRecipe COPYCAT_SLOPE = copycat(CCBlocks.COPYCAT_SLOPE, 2); + GeneratedRecipe COPYCAT_SHAFT = copycat(CCBlocks.COPYCAT_SHAFT, 2); + String currentFolder = ""; @@ -201,6 +206,10 @@ GeneratedRecipeBuilder.GeneratedRecipe copycat(ItemProviderEntry NonNullUnaryOperator RenderType::translucent) .color(() -> MultiStateCopycatBlock::wrappedColor); } + + public static NonNullUnaryOperator> functionalCopycat() { + return b -> b.initialProperties(SharedProperties::softMetal) + .blockstate((c, p) -> p.simpleBlock(c.get(), p.models() + .getExistingFile(p.mcLoc("air")))) + .initialProperties(SharedProperties::softMetal) + .properties(p -> p.noOcclusion() + .mapColor(MapColor.NONE)) + // fabric: only render base model on cutout. When rendering the wrapped model's material is copied. + .addLayer(() -> RenderType::cutout) + .color(() -> IFunctionalCopycatBlock::wrappedColor) + .transform(TagGen.axeOrPickaxe()); + } } diff --git a/forge/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json b/forge/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/lang/en_ud.json b/forge/src/generated/resources/assets/copycats/lang/en_ud.json index b15de372a..40d6f1160 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_ud.json @@ -81,6 +81,7 @@ "block.copycats.copycat_light_weighted_pressure_plate.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.summary": "˙ǝʇɐןd ǝɹnssǝɹd pǝʇɥbıǝʍ ʇɥbıן ןɐuoıʇɔunɟ ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_shaft": "ʇɟɐɥS ʇɐɔʎdoƆ", "block.copycats.copycat_slab": "qɐןS ʇɐɔʎdoƆ", "block.copycats.copycat_slab.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_slab.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/forge/src/generated/resources/assets/copycats/lang/en_us.json b/forge/src/generated/resources/assets/copycats/lang/en_us.json index 297e3a7a3..ed2c04a09 100644 --- a/forge/src/generated/resources/assets/copycats/lang/en_us.json +++ b/forge/src/generated/resources/assets/copycats/lang/en_us.json @@ -81,6 +81,7 @@ "block.copycats.copycat_light_weighted_pressure_plate.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.condition1": "When R-Clicked", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.summary": "_Converts_ any _full block_ into a functional light weighted pressure plate.", + "block.copycats.copycat_shaft": "Copycat Shaft", "block.copycats.copycat_slab": "Copycat Slab", "block.copycats.copycat_slab.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_slab.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json b/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json new file mode 100644 index 000000000..1da5c4a8d --- /dev/null +++ b/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/beam" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json new file mode 100644 index 000000000..bb90f7897 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "forge:ingots/zinc" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_shaft" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_shaft" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json new file mode 100644 index 000000000..25139ab89 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_shaft" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_shaft" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json new file mode 100644 index 000000000..4cdbc49d1 --- /dev/null +++ b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "forge:ingots/zinc" + }, + "result": "copycats:copycat_shaft" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 98ded5df5..1e1b882a6 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -25,6 +25,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_shaft" ] } \ No newline at end of file diff --git a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 98ded5df5..1e1b882a6 100644 --- a/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -25,6 +25,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_shaft" ] } \ No newline at end of file diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java new file mode 100644 index 000000000..6b7f21e91 --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java @@ -0,0 +1,62 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional.forge; + +import com.jozufozu.flywheel.core.model.BlockModel; +import com.jozufozu.flywheel.core.model.Bufferable; +import com.jozufozu.flywheel.core.model.ModelUtil; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.model.data.ModelData; + +public final class BakedModelWithDataBuilder implements Bufferable { + private final BakedModel model; + private BlockAndTintGetter renderWorld = VirtualEmptyBlockGetter.INSTANCE; + private BlockState referenceState = Blocks.AIR.defaultBlockState(); + private PoseStack poseStack = new PoseStack(); + private ModelData data = ModelUtil.VIRTUAL_DATA; + + public BakedModelWithDataBuilder(BakedModel model) { + this.model = model; + } + + public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { + this.renderWorld = renderWorld; + return this; + } + + public BakedModelWithDataBuilder withReferenceState(BlockState referenceState) { + this.referenceState = referenceState; + return this; + } + + public BakedModelWithDataBuilder withPoseStack(PoseStack poseStack) { + this.poseStack = poseStack; + return this; + } + + public BakedModelWithDataBuilder withData(ModelData data) { + this.data = data; + return this; + } + + @Override + public void bufferInto(VertexConsumer consumer, ModelBlockRenderer blockRenderer, RandomSource random) { + blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY, data, null); + } + + public BlockModel toModel(String name) { + return BlockModel.of(this, name); + } + + public BlockModel toModel() { + return toModel(referenceState.toString()); + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java new file mode 100644 index 000000000..c13f585d6 --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -0,0 +1,46 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional.forge; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.jozufozu.flywheel.core.model.ModelUtil; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.client.model.data.ModelProperty; + +public class FunctionalCopycatRenderHelperImpl { + + public static SuperByteBuffer copycatRender(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { + ModelData renderData = model.getModelData(be.getLevel(), be.getBlockPos(), be.getBlockState(), be.getCopycatBlockEntity().getModelData()); + ModelData.Builder builder = ModelData.builder(); + copyModelData(renderData, builder); + builder.with(ModelUtil.VIRTUAL_PROPERTY, true); + + ShadeSeparatedBufferedData bufferedData = new BakedModelWithDataBuilder(model) + .withReferenceState(be.getBlockState()) + .withPoseStack(ms) + .withData(builder.build()) + .build(); + SuperByteBuffer sbb = new SuperByteBuffer(bufferedData); + bufferedData.release(); + return sbb; + } + + public static ModelData.Builder mergeData(ModelData data1, ModelData data2) { + ModelData.Builder builder = ModelData.builder(); + copyModelData(data1, builder); + copyModelData(data2, builder); + return builder; + } + + static void copyModelData(ModelData from, ModelData.Builder to) { + for (ModelProperty property : from.getProperties()) { + copyModelProperty(to, from, property); + } + } + + static void copyModelProperty(ModelData.Builder to, ModelData from, ModelProperty property) { + to.with(property, from.get(property)); + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java new file mode 100644 index 000000000..0bf7fbb6a --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java @@ -0,0 +1,32 @@ +package com.copycatsplus.copycats.content.copycat.shaft.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.functional.forge.BakedModelWithDataBuilder; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.jozufozu.flywheel.core.model.ModelUtil; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.CreateClient; +import com.simibubi.create.content.decoration.copycat.CopycatModel; +import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.model.data.ModelData; +import net.minecraftforge.client.model.data.ModelProperty; +import org.jetbrains.annotations.NotNull; + + +public class CopycatShaftBlockEntityForge extends CopycatShaftBlockEntity { + public CopycatShaftBlockEntityForge(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + } + + @Override + public @NotNull ModelData getModelData() { + return getCopycatBlockEntity().getModelData(); + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java new file mode 100644 index 000000000..9525f0374 --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java @@ -0,0 +1,46 @@ +package com.copycatsplus.copycats.content.copycat.shaft.forge; + +import com.copycatsplus.copycats.content.copycat.base.model.functional.forge.FunctionalCopycatRenderHelperImpl; +import com.jozufozu.flywheel.core.model.ModelUtil; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockModel; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.model.data.ModelData; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class CopycatShaftModelForge extends BracketedKineticBlockModel { + private final BakedModel copycat; + + public CopycatShaftModelForge(BakedModel template, BakedModel copycat) { + super(template); + this.copycat = copycat; + } + + @Override + public @NotNull TextureAtlasSprite getParticleIcon(@NotNull ModelData data) { + return copycat.getParticleIcon(data); + } + + @Override + public @NotNull ModelData getModelData(BlockAndTintGetter world, BlockPos pos, BlockState state, ModelData blockEntityData) { + return FunctionalCopycatRenderHelperImpl.mergeData( + super.getModelData(world, pos, state, blockEntityData), + copycat.getModelData(world, pos, state, blockEntityData) + ).build(); + } + + @Override + public @NotNull List getQuads(BlockState state, Direction side, RandomSource rand, ModelData data, RenderType renderType) { + if (!ModelUtil.isVirtual(data)) return super.getQuads(state, side, rand, data, renderType); + return copycat.getQuads(state, side, rand, data, renderType); + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlockEntityTypesImpl.java b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlockEntityTypesImpl.java index 0ffcff5bd..0099a971f 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlockEntityTypesImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlockEntityTypesImpl.java @@ -4,6 +4,8 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.forge.MultiStateCopycatBlockEntityForge; import com.copycatsplus.copycats.content.copycat.ladder.CopycatLadderMultiStateBlockEntity; import com.copycatsplus.copycats.content.copycat.ladder.forge.CopycatLadderMultiStateBlockEntityForge; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.copycatsplus.copycats.content.copycat.shaft.forge.CopycatShaftBlockEntityForge; import com.tterrag.registrate.builders.BlockEntityBuilder; public class CCBlockEntityTypesImpl { @@ -16,4 +18,9 @@ public static BlockEntityBuilder.BlockEntityFactory getPlatformMultiStateLadder() { return CopycatLadderMultiStateBlockEntityForge::new; } + + + public static BlockEntityBuilder.BlockEntityFactory getPlatformShaft() { + return CopycatShaftBlockEntityForge::new; + } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlocksImpl.java b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlocksImpl.java index 4994be9d1..9842110b2 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlocksImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBlocksImpl.java @@ -1,7 +1,12 @@ package com.copycatsplus.copycats.forge; +import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftModel; +import com.copycatsplus.copycats.content.copycat.shaft.forge.CopycatShaftModelForge; import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.RegistrateBlockstateProvider; +import com.tterrag.registrate.util.nullness.NonNullFunction; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.world.level.block.Block; public class CCBlocksImpl { @@ -9,4 +14,8 @@ public class CCBlocksImpl { public static void getWrappedBlockState(DataGenContext c, RegistrateBlockstateProvider p, String name) { p.simpleBlock(c.getEntry(), p.models().withExistingParent(name, "block/barrier")); } + + public static BakedModel getShaftModel(BakedModel original, BakedModel copycat) { + return new CopycatShaftModelForge(original, copycat); + } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBuilderTransformersImpl.java b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBuilderTransformersImpl.java index ab8b51f97..45afebfd9 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/CCBuilderTransformersImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/CCBuilderTransformersImpl.java @@ -1,10 +1,13 @@ package com.copycatsplus.copycats.forge; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; import com.simibubi.create.foundation.data.SharedProperties; import com.simibubi.create.foundation.data.TagGen; import com.tterrag.registrate.builders.BlockBuilder; import com.tterrag.registrate.util.nullness.NonNullUnaryOperator; +import net.minecraft.world.level.block.Block; import net.minecraft.client.renderer.RenderType; import net.minecraft.world.level.material.MapColor; @@ -38,4 +41,19 @@ public static NonNullUnaryOperator RenderType::translucent) .color(() -> MultiStateCopycatBlock::wrappedColor); } + + public static NonNullUnaryOperator> functionalCopycat() { + return b -> b.initialProperties(SharedProperties::softMetal) + .blockstate((c, p) -> p.simpleBlock(c.get(), p.models() + .getExistingFile(p.mcLoc("air")))) + .initialProperties(SharedProperties::softMetal) + .properties(p -> p.noOcclusion() + .mapColor(MapColor.NONE)) + .addLayer(() -> RenderType::solid) + .addLayer(() -> RenderType::cutout) + .addLayer(() -> RenderType::cutoutMipped) + .addLayer(() -> RenderType::translucent) + .color(() -> IFunctionalCopycatBlock::wrappedColor) + .transform(TagGen.axeOrPickaxe()); + } } From 2da527ea7299e18850b58a6d7a8d18ef74f8a4a9 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 18:21:33 +0800 Subject: [PATCH 40/71] Implement GPU instancing --- .../copycats/CCBlockEntityTypes.java | 5 +- .../FunctionalCopycatRenderHelper.java | 32 +++++++++--- .../IFunctionalCopycatBlockInstance.java | 38 ++++++++++++++ .../functional/KineticCopycatRenderData.java | 4 ++ .../copycat/shaft/CopycatShaftInstance.java | 49 +++++++++++++++++++ .../FunctionalCopycatRenderHelperImpl.java | 8 +-- 6 files changed, 119 insertions(+), 17 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java index 8ea33ea58..0c8762f5f 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlockEntityTypes.java @@ -3,10 +3,9 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.ladder.CopycatLadderMultiStateBlockEntity; import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftInstance; import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftRenderer; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; -import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance; -import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer; import com.tterrag.registrate.builders.BlockEntityBuilder; import com.tterrag.registrate.util.entry.BlockEntityEntry; import dev.architectury.injectables.annotations.ExpectPlatform; @@ -58,7 +57,7 @@ public class CCBlockEntityTypes { public static final BlockEntityEntry COPYCAT_SHAFT = REGISTRATE.blockEntity("copycat_shaft", getPlatformShaft()) - .instance(() -> BracketedKineticBlockEntityInstance::new, false) + .instance(() -> CopycatShaftInstance::new, false) .validBlocks(CCBlocks.COPYCAT_SHAFT) .renderer(() -> CopycatShaftRenderer::new) .register(); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java index 1e4c97591..0fea31626 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/FunctionalCopycatRenderHelper.java @@ -2,6 +2,8 @@ import com.copycatsplus.copycats.CopycatsClient; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.jozufozu.flywheel.core.model.BlockModel; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBufferCache; @@ -13,21 +15,35 @@ public class FunctionalCopycatRenderHelper { public static final SuperByteBufferCache.Compartment KINETIC_COPYCAT = new SuperByteBufferCache.Compartment<>(); - public static SuperByteBuffer copycatRender(IFunctionalCopycatBlockEntity be) { - BlockRenderDispatcher dispatcher = Minecraft.getInstance() - .getBlockRenderer(); - return copycatRender(dispatcher.getBlockModel(be.getBlockState()), be, new PoseStack()); - } - public static SuperByteBuffer getBuffer(IFunctionalCopycatBlockEntity be) { return CopycatsClient.BUFFER_CACHE.get(KINETIC_COPYCAT, - new KineticCopycatRenderData(be.getBlockState(), be.getMaterial(), be.isCTEnabled()), + KineticCopycatRenderData.of(be), () -> copycatRender(be) ); } + public static BlockModel getInstanceModel(IFunctionalCopycatBlockEntity be, KineticCopycatRenderData renderData) { + ShadeSeparatedBufferedData data = getCopycatBuffer(be); + BlockModel blockModel = new BlockModel(data, renderData.toString()); + data.release(); + return blockModel; + } + + public static SuperByteBuffer copycatRender(IFunctionalCopycatBlockEntity be) { + ShadeSeparatedBufferedData bufferedData = getCopycatBuffer(be); + SuperByteBuffer sbb = new SuperByteBuffer(bufferedData); + bufferedData.release(); + return sbb; + } + + public static ShadeSeparatedBufferedData getCopycatBuffer(IFunctionalCopycatBlockEntity be) { + BlockRenderDispatcher dispatcher = Minecraft.getInstance() + .getBlockRenderer(); + return getCopycatBuffer(dispatcher.getBlockModel(be.getBlockState()), be, new PoseStack()); + } + @ExpectPlatform - public static SuperByteBuffer copycatRender(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { + public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { return null; } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java new file mode 100644 index 000000000..0da2e4059 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java @@ -0,0 +1,38 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.jozufozu.flywheel.api.Instancer; +import com.jozufozu.flywheel.api.Material; +import com.simibubi.create.content.kinetics.base.flwdata.RotatingData; + +import javax.annotation.Nullable; + +public interface IFunctionalCopycatBlockInstance { + + @Nullable + KineticCopycatRenderData getRenderData(); + + void setRenderData(KineticCopycatRenderData renderData); + + IFunctionalCopycatBlockEntity getBlockEntity(); + + Material getRotatingMaterial(); + + default Instancer getModel() { + KineticCopycatRenderData renderData = KineticCopycatRenderData.of(getBlockEntity()); + setRenderData(renderData); + return getRotatingMaterial().model(renderData, () -> FunctionalCopycatRenderHelper.getInstanceModel(getBlockEntity(), renderData)); + } + + default boolean shouldReset() { + if (getRenderData() == null) + return true; + if (getRenderData().enableCT() != getBlockEntity().isCTEnabled()) + return true; + if (!getRenderData().material().equals(getBlockEntity().getMaterial())) + return true; + if (!getRenderData().state().equals(getBlockEntity().getBlockState())) + return true; + return false; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java index 83d02d1c7..f0f4391b4 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java @@ -1,6 +1,10 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import net.minecraft.world.level.block.state.BlockState; public record KineticCopycatRenderData(BlockState state, BlockState material, boolean enableCT) { + public static KineticCopycatRenderData of(IFunctionalCopycatBlockEntity be) { + return new KineticCopycatRenderData(be.getBlockState(), be.getMaterial(), be.isCTEnabled()); + } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java new file mode 100644 index 000000000..836f73b8b --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java @@ -0,0 +1,49 @@ +package com.copycatsplus.copycats.content.copycat.shaft; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.model.functional.IFunctionalCopycatBlockInstance; +import com.copycatsplus.copycats.content.copycat.base.model.functional.KineticCopycatRenderData; +import com.jozufozu.flywheel.api.Instancer; +import com.jozufozu.flywheel.api.Material; +import com.jozufozu.flywheel.api.MaterialManager; +import com.simibubi.create.content.kinetics.base.flwdata.RotatingData; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance; + +public class CopycatShaftInstance extends BracketedKineticBlockEntityInstance implements IFunctionalCopycatBlockInstance { + protected KineticCopycatRenderData renderData; + + public CopycatShaftInstance(MaterialManager materialManager, BracketedKineticBlockEntity blockEntity) { + super(materialManager, blockEntity); + } + + @Override + public KineticCopycatRenderData getRenderData() { + return renderData; + } + + @Override + public void setRenderData(KineticCopycatRenderData renderData) { + this.renderData = renderData; + } + + @Override + public IFunctionalCopycatBlockEntity getBlockEntity() { + return (IFunctionalCopycatBlockEntity) blockEntity; + } + + @Override + public Material getRotatingMaterial() { + return super.getRotatingMaterial(); + } + + @Override + public Instancer getModel() { + return IFunctionalCopycatBlockInstance.super.getModel(); + } + + @Override + public boolean shouldReset() { + return IFunctionalCopycatBlockInstance.super.shouldReset(); + } +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java index c13f585d6..ea7143d32 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -4,27 +4,23 @@ import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.foundation.render.SuperByteBuffer; import net.minecraft.client.resources.model.BakedModel; import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.client.model.data.ModelProperty; public class FunctionalCopycatRenderHelperImpl { - public static SuperByteBuffer copycatRender(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { + public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { ModelData renderData = model.getModelData(be.getLevel(), be.getBlockPos(), be.getBlockState(), be.getCopycatBlockEntity().getModelData()); ModelData.Builder builder = ModelData.builder(); copyModelData(renderData, builder); builder.with(ModelUtil.VIRTUAL_PROPERTY, true); - ShadeSeparatedBufferedData bufferedData = new BakedModelWithDataBuilder(model) + return new BakedModelWithDataBuilder(model) .withReferenceState(be.getBlockState()) .withPoseStack(ms) .withData(builder.build()) .build(); - SuperByteBuffer sbb = new SuperByteBuffer(bufferedData); - bufferedData.release(); - return sbb; } public static ModelData.Builder mergeData(ModelData data1, ModelData data2) { From d4128d237b638cd3d4af66b0c012c0c2ddbd8ce0 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 18:34:47 +0800 Subject: [PATCH 41/71] Invalidate SuperByteBufferCache on reload --- .../IFunctionalCopycatBlockEntity.java | 2 +- .../copycat/shaft/CopycatShaftBlockEntity.java | 10 ---------- .../base}/CopycatBlockEntityAccessor.java | 2 +- .../base/functional/CreateClientMixin.java | 16 ++++++++++++++++ .../main/resources/copycats-common.mixins.json | 3 ++- 5 files changed, 20 insertions(+), 13 deletions(-) rename common/src/main/java/com/copycatsplus/copycats/mixin/{ => copycat/base}/CopycatBlockEntityAccessor.java (88%) create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CreateClientMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java index 629dde1f8..c8b091553 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlockEntity.java @@ -1,7 +1,7 @@ package com.copycatsplus.copycats.content.copycat.base.functional; import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.copycatsplus.copycats.mixin.CopycatBlockEntityAccessor; +import com.copycatsplus.copycats.mixin.copycat.base.CopycatBlockEntityAccessor; import com.simibubi.create.content.contraptions.ITransformableBlockEntity; import com.simibubi.create.content.contraptions.StructureTransform; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java index 2d5e0e7e9..105e5a064 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java @@ -1,21 +1,11 @@ package com.copycatsplus.copycats.content.copycat.shaft; import com.copycatsplus.copycats.CCBlockEntityTypes; -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; -import com.copycatsplus.copycats.mixin.CopycatBlockEntityAccessor; -import com.simibubi.create.CreateClient; -import com.simibubi.create.content.contraptions.ITransformableBlockEntity; -import com.simibubi.create.content.contraptions.StructureTransform; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; -import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; -import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement; -import com.simibubi.create.content.schematics.requirement.ItemRequirement; -import com.simibubi.create.foundation.utility.IPartialSafeNBT; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/CopycatBlockEntityAccessor.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityAccessor.java similarity index 88% rename from common/src/main/java/com/copycatsplus/copycats/mixin/CopycatBlockEntityAccessor.java rename to common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityAccessor.java index 87359c0a3..b4f8f8336 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/CopycatBlockEntityAccessor.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/CopycatBlockEntityAccessor.java @@ -1,4 +1,4 @@ -package com.copycatsplus.copycats.mixin; +package com.copycatsplus.copycats.mixin.copycat.base; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; import net.minecraft.nbt.CompoundTag; diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CreateClientMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CreateClientMixin.java new file mode 100644 index 000000000..7b1d4370f --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CreateClientMixin.java @@ -0,0 +1,16 @@ +package com.copycatsplus.copycats.mixin.copycat.base.functional; + +import com.copycatsplus.copycats.CopycatsClient; +import com.simibubi.create.CreateClient; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = CreateClient.class, remap = false) +public class CreateClientMixin { + @Inject(method = "invalidateRenderers", at = @At("HEAD")) + private static void invalidateRenderers(CallbackInfo ci) { + CopycatsClient.BUFFER_CACHE.invalidate(); + } +} diff --git a/common/src/main/resources/copycats-common.mixins.json b/common/src/main/resources/copycats-common.mixins.json index 575e52c2a..218f9c981 100644 --- a/common/src/main/resources/copycats-common.mixins.json +++ b/common/src/main/resources/copycats-common.mixins.json @@ -5,7 +5,6 @@ "plugin": "com.copycatsplus.copycats.mixin.MixinPlugin", "compatibilityLevel": "JAVA_17", "mixins": [ - "CopycatBlockEntityAccessor", "compat.additionalplacements.ConfigCommonMixin", "compat.additionalplacements.PlacementBlockMixin", "compat.diagonalfences.FenceBlockMixin", @@ -14,9 +13,11 @@ "compat.rubidium.BlockRendererMixin", "copycat.TrackPlacementMixin", "copycat.base.ConnectedTextureBehaviourMixin", + "copycat.base.CopycatBlockEntityAccessor", "copycat.base.CopycatBlockEntityMixin", "copycat.base.CopycatBlockMixin", "copycat.base.FilteredBlockAndTintGetterAccessor", + "copycat.base.functional.CreateClientMixin", "copycat.base.multistate.AirCurrentMixin", "copycat.base.multistate.ContraptionMixin", "copycat.base.multistate.LevelChunkMixin", From f6a67936570f0295179e379e116c7d7eea5d6d54 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 19:26:45 +0800 Subject: [PATCH 42/71] Update create to 0.5.1f to fix a rendering issue --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1e8a8d7f4..341373fd5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -31,11 +31,11 @@ rubidium_curse_id=4952685 double_slabs_curse_id=3873442 #Forge Properties -create_forge_version=0.5.1.d-12 +create_forge_version=0.5.1.f-26 create_forge_range=[0.5.1.d,) registrate_forge_version=MC1.20-1.3.3 flywheel_forge_minecraft_version=1.20.1 -flywheel_forge_version=0.6.9-5 +flywheel_forge_version=0.6.10-7 # JEI 10+ seems to have issues on Forge, so the versions must be different for now. # 1.19 edit: no version < 11 exists, so use that jei_forge_version=15.3.0.4 rubidium_forge_curse_id=4952685 From 7f3b44c8545c169fc9c334ac5563e234dc84925a Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 19:29:40 +0800 Subject: [PATCH 43/71] Update item model for shaft --- .../com/copycatsplus/copycats/CCBlocks.java | 2 +- .../models/block/copycat_base/shaft.json | 50 +++++++++++++++++++ .../copycats/models/item/copycat_shaft.json | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 common/src/main/resources/assets/copycats/models/block/copycat_base/shaft.json diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index cad0212cd..9e1a5dd59 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -496,7 +496,7 @@ public class CCBlocks { .transform(BlockStressDefaults.setNoImpact()) .onRegister(CreateRegistrate.blockModel(() -> model -> getShaftModel(model, SimpleCopycatPart.create(model, new CopycatShaftModel())))) .item() - .transform(customItemModel("copycat_base", "beam")) + .transform(customItemModel("copycat_base", "shaft")) .register(); @ExpectPlatform diff --git a/common/src/main/resources/assets/copycats/models/block/copycat_base/shaft.json b/common/src/main/resources/assets/copycats/models/block/copycat_base/shaft.json new file mode 100644 index 000000000..ef995562c --- /dev/null +++ b/common/src/main/resources/assets/copycats/models/block/copycat_base/shaft.json @@ -0,0 +1,50 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "2": "create:block/copycat_base", + "particle": "create:block/copycat_base" + }, + "elements": [ + { + "from": [6, 0, 6], + "to": [8, 16, 8], + "faces": { + "north": {"uv": [14, 0, 16, 16], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 16], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [0, 14, 2, 16], "texture": "#2"} + } + }, + { + "from": [8, 0, 6], + "to": [10, 16, 8], + "faces": { + "north": {"uv": [0, 0, 2, 16], "texture": "#2"}, + "east": {"uv": [14, 0, 16, 16], "texture": "#2"}, + "up": {"uv": [14, 0, 16, 2], "texture": "#2"}, + "down": {"uv": [14, 14, 16, 16], "texture": "#2"} + } + }, + { + "from": [6, 0, 8], + "to": [8, 16, 10], + "faces": { + "south": {"uv": [0, 0, 2, 16], "texture": "#2"}, + "west": {"uv": [14, 0, 16, 16], "texture": "#2"}, + "up": {"uv": [0, 14, 2, 16], "texture": "#2"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#2"} + } + }, + { + "from": [8, 0, 8], + "to": [10, 16, 10], + "faces": { + "east": {"uv": [0, 0, 2, 16], "texture": "#2"}, + "south": {"uv": [14, 0, 16, 16], "texture": "#2"}, + "up": {"uv": [14, 14, 16, 16], "texture": "#2"}, + "down": {"uv": [14, 0, 16, 2], "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json b/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json index 1da5c4a8d..bd5cfb8df 100644 --- a/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json +++ b/forge/src/generated/resources/assets/copycats/models/item/copycat_shaft.json @@ -1,3 +1,3 @@ { - "parent": "copycats:block/copycat_base/beam" + "parent": "copycats:block/copycat_base/shaft" } \ No newline at end of file From 9aae829882278ad8a4b3de8ade59ce65c0c81619 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Mon, 24 Jun 2024 20:35:33 +0800 Subject: [PATCH 44/71] Make all copycat-like classes implement functional interfaces --- .../functional/IFunctionalCopycatBlock.java | 2 +- .../multistate/MultiStateCopycatBlock.java | 8 ++-- .../MultiStateCopycatBlockEntity.java | 12 +++-- .../PlacementBlockMixin.java | 4 +- .../rubidium/BlockOcclusionCacheMixin.java | 3 +- .../functional/CopycatBlockEntityMixin.java | 13 ++++++ .../base/functional/CopycatBlockMixin.java | 45 +++++++++++++++++++ .../resources/copycats-common.mixins.json | 2 + .../doubleslabs/DSConfigCommonMixin.java | 5 ++- 9 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockEntityMixin.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java index d7cd1e187..382d8c053 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -87,7 +87,7 @@ default BlockState getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack return null; Block block = bi.getBlock(); - if (block instanceof CopycatBlock) + if (block instanceof CopycatBlock || block instanceof IFunctionalCopycatBlock) return null; BlockState appliedState = block.defaultBlockState(); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java index 1607e7da7..8799932fa 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlock.java @@ -5,6 +5,7 @@ import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.IStateType; import com.copycatsplus.copycats.content.copycat.base.StateType; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.content.decoration.copycat.CopycatBlock; @@ -62,7 +63,7 @@ import static net.minecraft.core.Direction.Axis; -public abstract class MultiStateCopycatBlock extends Block implements IBE, IWrenchable, ISpecialBlockItemRequirement, IStateType { +public abstract class MultiStateCopycatBlock extends Block implements IFunctionalCopycatBlock, IBE, IWrenchable, ISpecialBlockItemRequirement, IStateType { public static final EnumProperty TRANSFORM = CCBlockStateProperties.TRANSFORM; @@ -131,8 +132,7 @@ public BlockEntityTicker getTicker(Level p_153212_, B @Override public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { - onWrenched(state, context); - return IWrenchable.super.onSneakWrenched(state, context); + return IFunctionalCopycatBlock.super.onSneakWrenched(state, context); } @Override @@ -250,7 +250,7 @@ public BlockState getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack i return null; Block block = bi.getBlock(); - if (block instanceof MultiStateCopycatBlock || block instanceof CopycatBlock) + if (block instanceof IFunctionalCopycatBlock || block instanceof CopycatBlock) return null; BlockState appliedState = block.defaultBlockState(); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java index 0a9fd872e..6b2c44334 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/multistate/MultiStateCopycatBlockEntity.java @@ -2,6 +2,7 @@ import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.config.CCConfigs; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import com.simibubi.create.content.contraptions.ITransformableBlockEntity; import com.simibubi.create.content.contraptions.StructureTransform; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; @@ -31,7 +32,7 @@ import java.util.Set; public abstract class MultiStateCopycatBlockEntity extends SmartBlockEntity implements - ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT { + IFunctionalCopycatBlockEntity, ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT { private final MaterialItemStorage materialItemStorage; @@ -44,6 +45,11 @@ public MultiStateCopycatBlockEntity(BlockEntityType type, BlockPos pos, Block } } + @Override + public CopycatBlockEntity getCopycatBlockEntity() { + return null; + } + @Override public void setLevel(@NotNull Level level) { super.setLevel(level); @@ -170,14 +176,14 @@ public void writeSafe(CompoundTag tag) { } @Override - protected void write(CompoundTag tag, boolean clientPacket) { + public void write(CompoundTag tag, boolean clientPacket) { super.write(tag, clientPacket); tag.put("material_data", materialItemStorage.serialize()); } @Override - protected void read(CompoundTag tag, boolean clientPacket) { + public void read(CompoundTag tag, boolean clientPacket) { super.read(tag, clientPacket); if (getBlockState().getBlock() instanceof MultiStateCopycatBlock mscb) { boolean anyUpdated = materialItemStorage.deserialize(tag.getCompound("material_data")); diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java index 60282f069..cda7eba74 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/additionalplacements/PlacementBlockMixin.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats.mixin.compat.additionalplacements; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.pressure_plate.WrappedPressurePlate; import com.copycatsplus.copycats.content.copycat.stairs.WrappedStairsBlock; import com.firemerald.additionalplacements.block.AdditionalPlacementBlock; @@ -36,7 +37,8 @@ private void forCopycatBlocks(CallbackInfoReturnable cir) { block instanceof WrappedPressurePlate.LightWeighted || block instanceof WrappedPressurePlate.HeavyWeighted || block instanceof WrappedStairsBlock || - block instanceof CopycatBlock) + block instanceof CopycatBlock || + block instanceof IFunctionalCopycatBlock) cir.setReturnValue(false); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java index 088ad0f69..ad160ba1b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/compat/rubidium/BlockOcclusionCacheMixin.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats.mixin.compat.rubidium; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.simibubi.create.content.decoration.copycat.CopycatBlock; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -19,7 +20,7 @@ public class BlockOcclusionCacheMixin { //FIXME: Needs to be done more specifically. Or preferably without stopping their culling on us full stop but right now nothing i've tried seems to be working that makes sense @Inject(method = "shouldDrawSide", at = @At("HEAD"), cancellable = true) private void copycats$stopCullingUs(BlockState selfState, BlockGetter view, BlockPos pos, Direction facing, CallbackInfoReturnable cir) { - if (selfState.getBlock() instanceof CopycatBlock cb) { + if (selfState.getBlock() instanceof CopycatBlock || selfState.getBlock() instanceof IFunctionalCopycatBlock) { cir.setReturnValue(true); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockEntityMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockEntityMixin.java new file mode 100644 index 000000000..4f5909874 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockEntityMixin.java @@ -0,0 +1,13 @@ +package com.copycatsplus.copycats.mixin.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(CopycatBlockEntity.class) +public abstract class CopycatBlockEntityMixin implements IFunctionalCopycatBlockEntity { + @Override + public CopycatBlockEntity getCopycatBlockEntity() { + return (CopycatBlockEntity) (Object) this; + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockMixin.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockMixin.java new file mode 100644 index 000000000..881d39bf0 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/base/functional/CopycatBlockMixin.java @@ -0,0 +1,45 @@ +package com.copycatsplus.copycats.mixin.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(CopycatBlock.class) +public abstract class CopycatBlockMixin implements IFunctionalCopycatBlock { + @Inject( + method = "getAcceptedBlockState", + at = @At("HEAD"), + cancellable = true + ) + private void getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack item, Direction face, CallbackInfoReturnable cir) { + if (!(item.getItem() instanceof BlockItem bi)) + return; + + Block block = bi.getBlock(); + if (block instanceof IFunctionalCopycatBlock) + cir.setReturnValue(null); + } + + @Inject( + method = "getMaterial", + at = @At("HEAD"), + cancellable = true + ) + private static void getMaterial(BlockGetter reader, BlockPos targetPos, CallbackInfoReturnable cir) { + if (reader.getBlockEntity(targetPos) instanceof IFunctionalCopycatBlockEntity cbe) + cir.setReturnValue(cbe.getMaterial()); + } +} diff --git a/common/src/main/resources/copycats-common.mixins.json b/common/src/main/resources/copycats-common.mixins.json index 218f9c981..8ff1dd402 100644 --- a/common/src/main/resources/copycats-common.mixins.json +++ b/common/src/main/resources/copycats-common.mixins.json @@ -17,6 +17,8 @@ "copycat.base.CopycatBlockEntityMixin", "copycat.base.CopycatBlockMixin", "copycat.base.FilteredBlockAndTintGetterAccessor", + "copycat.base.functional.CopycatBlockEntityMixin", + "copycat.base.functional.CopycatBlockMixin", "copycat.base.functional.CreateClientMixin", "copycat.base.multistate.AirCurrentMixin", "copycat.base.multistate.ContraptionMixin", diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/compat/doubleslabs/DSConfigCommonMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/compat/doubleslabs/DSConfigCommonMixin.java index 983a1e481..6e8afaf99 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/compat/doubleslabs/DSConfigCommonMixin.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/compat/doubleslabs/DSConfigCommonMixin.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.forge.mixin.compat.doubleslabs; import cjminecraft.doubleslabs.common.config.DSConfig; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.simibubi.create.content.decoration.copycat.CopycatBlock; import net.minecraft.world.level.block.Block; import org.spongepowered.asm.mixin.Mixin; @@ -15,14 +16,14 @@ public class DSConfigCommonMixin { @Inject(method = "isBlacklistedHorizontalSlab", at = @At("HEAD"), cancellable = true, remap = false) private void copycats$alwaysBlacklistHorizontal(Block block, CallbackInfoReturnable cir) { - if (block instanceof CopycatBlock) { + if (block instanceof CopycatBlock || block instanceof IFunctionalCopycatBlock) { cir.setReturnValue(false); } } @Inject(method = "isBlacklistedVerticalSlab", at = @At("HEAD"), cancellable = true, remap = false) private void copycats$alwaysBlacklistVertical(Block block, CallbackInfoReturnable cir) { - if (block instanceof CopycatBlock) { + if (block instanceof CopycatBlock || block instanceof IFunctionalCopycatBlock) { cir.setReturnValue(false); } } From 60421bad2632eb4be34e7d8d78a118635fc9d801 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 12:16:43 +0800 Subject: [PATCH 45/71] Each feature can now have multiple categories --- .../com/copycatsplus/copycats/CCBlocks.java | 28 +++++++++---------- .../copycats/config/FeatureCategory.java | 5 +++- .../copycats/config/FeatureToggle.java | 27 ++++++++++-------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index 26a20f139..1b6ad69b8 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -121,7 +121,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_BOARD = REGISTRATE.block("copycat_board", CopycatBoardBlock::new) .transform(CCBuilderTransformers.multiCopycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.MULTISTATES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleMultiStateCopycatPart.create(model, new CopycatMultiBoardModel()))) .loot(CCLootGen.build(CCLootGen.lootForDirections())) .item() @@ -136,7 +136,7 @@ public class CCBlocks { .noCollission()) .tag(BlockTags.BUTTONS) .tag(BlockTags.WOODEN_BUTTONS) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatButtonModel()))) .item() .transform(customItemModel("copycat_base", "button")) @@ -149,7 +149,7 @@ public class CCBlocks { .noCollission()) .tag(BlockTags.BUTTONS) .tag(BlockTags.STONE_BUTTONS) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatButtonModel()))) .item() .transform(customItemModel("copycat_base", "button")) @@ -176,7 +176,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_BYTE = REGISTRATE.block("copycat_byte", CopycatByteBlock::new) .transform(CCBuilderTransformers.multiCopycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.MULTISTATES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleMultiStateCopycatPart.create(model, new CopycatMultiByteModel()))) .loot(CCLootGen.build(CCLootGen.lootForBytes())) .item() @@ -236,7 +236,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_HALF_LAYER = REGISTRATE.block("copycat_half_layer", CopycatHalfLayerBlock::new) .transform(CCBuilderTransformers.multiCopycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.MULTISTATES, FeatureCategory.STACKABLES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleMultiStateCopycatPart.create(model, new CopycatMultiHalfLayerModel()))) .loot(CCLootGen.build( CCLootGen.lootForLayers(CopycatHalfLayerBlock.NEGATIVE_LAYERS), @@ -277,7 +277,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_LAYER = REGISTRATE.block("copycat_layer", CopycatLayerBlock::new) .transform(BuilderTransformers.copycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.STACKABLES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatLayerModel()))) .loot(CCLootGen.build(CCLootGen.lootForLayers())) .item() @@ -300,7 +300,7 @@ public class CCBlocks { .noCollission()) .tag(BlockTags.PRESSURE_PLATES) .tag(BlockTags.WOODEN_PRESSURE_PLATES) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatPressurePlateModel()))) .item() .transform(customItemModel("copycat_base", "pressure_plate")) @@ -322,7 +322,7 @@ public class CCBlocks { .noCollission()) .tag(BlockTags.PRESSURE_PLATES) .tag(BlockTags.STONE_PRESSURE_PLATES) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatPressurePlateModel()))) .item() .transform(customItemModel("copycat_base", "pressure_plate")) @@ -342,7 +342,7 @@ public class CCBlocks { .properties(p -> p.isValidSpawn((state, level, pos, entity) -> false) .noCollission()) .tag(BlockTags.PRESSURE_PLATES) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatPressurePlateModel()))) .item() .transform(customItemModel("copycat_base", "pressure_plate")) @@ -362,7 +362,7 @@ public class CCBlocks { .properties(p -> p.isValidSpawn((state, level, pos, entity) -> false) .noCollission()) .tag(BlockTags.PRESSURE_PLATES) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.REDSTONE)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatPressurePlateModel()))) .item() .transform(customItemModel("copycat_base", "pressure_plate")) @@ -372,7 +372,7 @@ public class CCBlocks { REGISTRATE.block("copycat_slab", CopycatSlabBlock::new) .transform(CCBuilderTransformers.multiCopycat()) .tag(BlockTags.SLABS) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.MULTISTATES)) .loot((lt, block) -> lt.add(block, lt.createSlabItemTable(block))) .onRegister(blockModel(() -> model -> SimpleMultiStateCopycatPart.create(model, new CopycatMultiSlabModel()))) .item() @@ -383,7 +383,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_SLICE = REGISTRATE.block("copycat_slice", CopycatSliceBlock::new) .transform(BuilderTransformers.copycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.STACKABLES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatSliceModel()))) .loot(CCLootGen.build(CCLootGen.lootForLayers())) .item() @@ -444,7 +444,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_VERTICAL_SLICE = REGISTRATE.block("copycat_vertical_slice", CopycatVerticalSliceBlock::new) .transform(BuilderTransformers.copycat()) - .transform(FeatureToggle.register()) + .transform(FeatureToggle.register(FeatureCategory.STACKABLES)) .onRegister(CreateRegistrate.blockModel(() -> model -> SimpleCopycatPart.create(model, new CopycatVerticalSliceModel()))) .loot(CCLootGen.build(CCLootGen.lootForLayers())) .item() @@ -502,7 +502,7 @@ public class CCBlocks { public static final BlockEntry COPYCAT_SLOPE_LAYER = REGISTRATE.block("copycat_slope_layer", CopycatSlopeLayerBlock::new) .transform(BuilderTransformers.copycat()) - .transform(FeatureToggle.register(FeatureCategory.SLOPES)) + .transform(FeatureToggle.register(FeatureCategory.SLOPES, FeatureCategory.STACKABLES)) .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeLayerModel(false), new CopycatSlopeLayerModel(true)))) .loot(CCLootGen.build(CCLootGen.lootForLayers())) .item() diff --git a/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java b/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java index ff3d823d9..2ff0ac1cb 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/FeatureCategory.java @@ -4,7 +4,10 @@ import org.jetbrains.annotations.NotNull; public enum FeatureCategory implements StringRepresentable { - SLOPES("All copycats with a sloped surface"); + SLOPES("All copycats with a sloped surface"), + MULTISTATES("All copycats that support multiple materials in a single block"), + STACKABLES("All copycats that can be resized by putting in more of the same copycat"), + REDSTONE("All copycats that can emit a redstone signal"); private final String description; diff --git a/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java b/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java index 452353b95..ff53ba114 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/FeatureToggle.java @@ -19,24 +19,24 @@ public class FeatureToggle { public static final Set TOGGLEABLE_FEATURES = new HashSet<>(); public static final Map DEPENDENT_FEATURES = new HashMap<>(); - public static final Map FEATURE_CATEGORIES = new HashMap<>(); + public static final Map> FEATURE_CATEGORIES = new HashMap<>(); public static void register(ResourceLocation key) { TOGGLEABLE_FEATURES.add(key); } - public static void register(ResourceLocation key, FeatureCategory category) { + public static void register(ResourceLocation key, FeatureCategory... categories) { register(key); - FEATURE_CATEGORIES.put(key, category); + FEATURE_CATEGORIES.put(key, Set.of(categories)); } public static void registerDependent(ResourceLocation key, ResourceLocation dependency) { DEPENDENT_FEATURES.put(key, dependency); } - public static void registerDependent(ResourceLocation key, ResourceLocation dependency, FeatureCategory category) { + public static void registerDependent(ResourceLocation key, ResourceLocation dependency, FeatureCategory... categories) { registerDependent(key, dependency); - FEATURE_CATEGORIES.put(key, category); + FEATURE_CATEGORIES.put(key, Set.of(categories)); } /** @@ -52,9 +52,9 @@ public static > NonNullUnaryOpe /** * Register this object to be a feature that is toggleable by the user */ - public static > NonNullUnaryOperator register(FeatureCategory category) { + public static > NonNullUnaryOperator register(FeatureCategory... categories) { return b -> { - register(new ResourceLocation(b.getOwner().getModid(), b.getName()), category); + register(new ResourceLocation(b.getOwner().getModid(), b.getName()), categories); return b; }; } @@ -74,9 +74,9 @@ public static > NonNullUnaryOpe * Register this object to be dependent on another feature. * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. */ - public static > NonNullUnaryOperator registerDependent(ResourceLocation dependency, FeatureCategory category) { + public static > NonNullUnaryOperator registerDependent(ResourceLocation dependency, FeatureCategory... categories) { return b -> { - registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency, category); + registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency, categories); return b; }; } @@ -96,9 +96,9 @@ public static > NonNullUnaryOpe * Register this object to be dependent on another feature. * This object cannot be toggled directly, and will only be enabled if the dependency is enabled. */ - public static > NonNullUnaryOperator registerDependent(BlockEntry dependency, FeatureCategory category) { + public static > NonNullUnaryOperator registerDependent(BlockEntry dependency, FeatureCategory... categories) { return b -> { - registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency.getId(), category); + registerDependent(new ResourceLocation(b.getOwner().getModid(), b.getName()), dependency.getId(), categories); return b; }; } @@ -120,7 +120,10 @@ private static CFeatureCategories getCategories() { */ public static boolean isEnabled(ResourceLocation key) { if (FEATURE_CATEGORIES.containsKey(key)) { - if (!getCategories().isEnabled(FEATURE_CATEGORIES.get(key))) return false; + Set categories = FEATURE_CATEGORIES.get(key); + for (FeatureCategory category : categories) { + if (!getCategories().isEnabled(category)) return false; + } } if (getToggles().hasToggle(key)) { return getToggles().isEnabled(key); From 538b67c5d889491abaaa590056a1d913738c9493 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 12:23:20 +0800 Subject: [PATCH 46/71] Reorganize creative tab --- .../copycatsplus/copycats/CCCreativeTabs.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index d3ae18911..f2f8e92aa 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -12,33 +12,37 @@ public class CCCreativeTabs { public static final List> ITEMS = List.of( - CCBlocks.COPYCAT_BEAM, + /* Vanilla blocks */ CCBlocks.COPYCAT_BLOCK, - CCBlocks.COPYCAT_BOARD, - CCItems.COPYCAT_BOX, - CCBlocks.COPYCAT_BYTE, - CCItems.COPYCAT_CATWALK, - CCBlocks.COPYCAT_FENCE, - CCBlocks.COPYCAT_FENCE_GATE, - CCBlocks.COPYCAT_GHOST_BLOCK, - CCBlocks.COPYCAT_HALF_LAYER, - CCBlocks.COPYCAT_HALF_PANEL, - CCBlocks.COPYCAT_HEAVY_WEIGHTED_PRESSURE_PLATE, - CCBlocks.COPYCAT_LADDER, - CCBlocks.COPYCAT_LAYER, - CCBlocks.COPYCAT_LIGHT_WEIGHTED_PRESSURE_PLATE, CCBlocks.COPYCAT_SLAB, - CCBlocks.COPYCAT_SLICE, CCBlocks.COPYCAT_STAIRS, CCBlocks.COPYCAT_VERTICAL_STAIRS, - CCBlocks.COPYCAT_STONE_BUTTON, - CCBlocks.COPYCAT_STONE_PRESSURE_PLATE, - CCBlocks.COPYCAT_TRAPDOOR, - CCBlocks.COPYCAT_VERTICAL_SLICE, - CCBlocks.COPYCAT_VERTICAL_STEP, + CCBlocks.COPYCAT_FENCE, + CCBlocks.COPYCAT_FENCE_GATE, CCBlocks.COPYCAT_WALL, + CCBlocks.COPYCAT_TRAPDOOR, + CCBlocks.COPYCAT_LADDER, CCBlocks.COPYCAT_WOODEN_BUTTON, + CCBlocks.COPYCAT_STONE_BUTTON, CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, + CCBlocks.COPYCAT_STONE_PRESSURE_PLATE, + CCBlocks.COPYCAT_LIGHT_WEIGHTED_PRESSURE_PLATE, + CCBlocks.COPYCAT_HEAVY_WEIGHTED_PRESSURE_PLATE, + /* Simple copycats */ + CCBlocks.COPYCAT_VERTICAL_STEP, + CCBlocks.COPYCAT_BEAM, + CCBlocks.COPYCAT_SLICE, + CCBlocks.COPYCAT_VERTICAL_SLICE, + CCBlocks.COPYCAT_GHOST_BLOCK, + CCBlocks.COPYCAT_LAYER, + CCBlocks.COPYCAT_HALF_PANEL, + /* Multistates */ + CCBlocks.COPYCAT_BYTE, + CCBlocks.COPYCAT_BOARD, + CCItems.COPYCAT_CATWALK, + CCItems.COPYCAT_BOX, + CCBlocks.COPYCAT_HALF_LAYER, + /* Slopes */ CCBlocks.COPYCAT_SLOPE, CCBlocks.COPYCAT_VERTICAL_SLOPE, CCBlocks.COPYCAT_SLOPE_LAYER From 2c33faff0095de03304a4be2faa6e0ce98a647f0 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 12:31:21 +0800 Subject: [PATCH 47/71] Implement placement helper for slope and vertical slope --- .../copycat/slope/CopycatSlopeBlock.java | 47 +++++++++++++++++++ .../CopycatVerticalSlopeBlock.java | 3 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java index 7e6a9dce9..693feb995 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -1,15 +1,26 @@ package com.copycatsplus.copycats.content.copycat.slope; +import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.copycatsplus.copycats.content.copycat.base.IStateType; +import com.simibubi.create.foundation.placement.IPlacementHelper; +import com.simibubi.create.foundation.placement.PlacementHelpers; +import com.simibubi.create.foundation.placement.PoleHelper; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; @@ -20,17 +31,21 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.NotNull; import java.util.Optional; +import java.util.function.Predicate; public class CopycatSlopeBlock extends CTWaterloggedCopycatBlock implements IStateType, ICustomCTBlocking { public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final EnumProperty HALF = BlockStateProperties.HALF; + private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); + public CopycatSlopeBlock(Properties pProperties) { super(pProperties); registerDefaultState(defaultBlockState() @@ -39,6 +54,23 @@ public CopycatSlopeBlock(Properties pProperties) { ); } + @Override + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult ray) { + + if (!player.isShiftKeyDown() && player.mayBuild()) { + ItemStack heldItem = player.getItemInHand(hand); + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem)) { + placementHelper.getOffset(player, world, state, pos, ray) + .placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); + return InteractionResult.SUCCESS; + } + } + + return super.use(state, world, pos, player, hand, ray); + } + @Override public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { @@ -180,4 +212,19 @@ public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState sta public @NotNull BlockState mirror(@NotNull BlockState pState, @NotNull Mirror pMirror) { return pState.setValue(FACING, pMirror.mirror(pState.getValue(FACING))); } + + @MethodsReturnNonnullByDefault + private static class PlacementHelper extends PoleHelper { + + private PlacementHelper() { + super(CCBlocks.COPYCAT_SLOPE::has, state -> state.getValue(FACING).getClockWise().getAxis(), FACING); + } + + @Override + public Predicate getItemPredicate() { + return i -> i.getItem() instanceof BlockItem + && (((BlockItem) i.getItem()).getBlock() instanceof CopycatSlopeBlock); + } + + } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java index a301cb3ac..6f9bc2a73 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/vertical_slope/CopycatVerticalSlopeBlock.java @@ -30,7 +30,6 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; @@ -259,7 +258,7 @@ public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState sta private static class PlacementHelper extends PoleHelper { private PlacementHelper() { - super(CCBlocks.COPYCAT_VERTICAL_STEP::has, $ -> Axis.Y, FACING); + super(CCBlocks.COPYCAT_VERTICAL_SLOPE::has, $ -> Axis.Y, FACING); } @Override From 29d7202b409d4eae68d155083e57427164b0767c Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 14:21:32 +0800 Subject: [PATCH 48/71] Fix copycat shaft interaction --- .../content/copycat/shaft/CopycatShaftBlock.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java index c08a793a8..37e4c087b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java @@ -27,25 +27,25 @@ public CopycatShaftBlock(Properties properties) { @Override public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { - InteractionResult result = super.onSneakWrenched(state, context); + InteractionResult result = IFunctionalCopycatBlock.super.onSneakWrenched(state, context); if (result.consumesAction()) { return result; } - return IFunctionalCopycatBlock.super.onSneakWrenched(state, context); + return super.onSneakWrenched(state, context); } @Override public InteractionResult onWrenched(BlockState state, UseOnContext context) { - InteractionResult result = super.onWrenched(state, context); + InteractionResult result = IFunctionalCopycatBlock.super.onWrenched(state, context); if (result.consumesAction()) { return result; } - return IFunctionalCopycatBlock.super.onWrenched(state, context); + return super.onWrenched(state, context); } @Override public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) { - InteractionResult result = super.use(state, world, pos, player, hand, ray); + InteractionResult result = IFunctionalCopycatBlock.super.use(state, world, pos, player, hand, ray); if (result.consumesAction()) { return result; } @@ -59,7 +59,7 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player } } - return IFunctionalCopycatBlock.super.use(state, world, pos, player, hand, ray); + return super.use(state, world, pos, player, hand, ray); } @Override From 06d7b50b97c4f2303f755ffd5e1aa014f26c2e39 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 14:21:46 +0800 Subject: [PATCH 49/71] Fix copycat shaft transparency when rendering with instancing --- .../copycats/content/copycat/shaft/CopycatShaftInstance.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java index 836f73b8b..0197bb888 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java @@ -9,6 +9,7 @@ import com.simibubi.create.content.kinetics.base.flwdata.RotatingData; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance; +import com.simibubi.create.foundation.render.AllMaterialSpecs; public class CopycatShaftInstance extends BracketedKineticBlockEntityInstance implements IFunctionalCopycatBlockInstance { protected KineticCopycatRenderData renderData; @@ -34,7 +35,8 @@ public IFunctionalCopycatBlockEntity getBlockEntity() { @Override public Material getRotatingMaterial() { - return super.getRotatingMaterial(); + return materialManager.defaultTransparent() + .material(AllMaterialSpecs.ROTATING); } @Override From 7c14566512aad79a5b277cf305898c3738fd5fe6 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 16:38:58 +0800 Subject: [PATCH 50/71] Fix block colors for copycat shaft (using a constant color for all biomes) --- .../copycat/base/functional/IFunctionalCopycatBlock.java | 5 ++--- .../model/functional/forge/BakedModelWithDataBuilder.java | 8 +++++++- .../forge/FunctionalCopycatRenderHelperImpl.java | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java index 382d8c053..2a13eb005 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -251,11 +251,10 @@ static class WrappedBlockColor implements BlockColor { @Override public int getColor(BlockState pState, @Nullable BlockAndTintGetter pLevel, @Nullable BlockPos pPos, int pTintIndex) { - if (pLevel == null || pPos == null) - return GrassColor.get(0.5D, 1.0D); return Minecraft.getInstance() .getBlockColors() - .getColor(getMaterial(pLevel, pPos), pLevel, pPos, pTintIndex); + // we don't want colors to change based on biome because we are caching the render result + .getColor(getMaterial(pLevel, pPos), pLevel, null, pTintIndex); } } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java index 6b7f21e91..b647ac4b2 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java @@ -21,12 +21,18 @@ public final class BakedModelWithDataBuilder implements Bufferable { private BlockAndTintGetter renderWorld = VirtualEmptyBlockGetter.INSTANCE; private BlockState referenceState = Blocks.AIR.defaultBlockState(); private PoseStack poseStack = new PoseStack(); + private BlockPos renderPos = BlockPos.ZERO; private ModelData data = ModelUtil.VIRTUAL_DATA; public BakedModelWithDataBuilder(BakedModel model) { this.model = model; } + public BakedModelWithDataBuilder withRenderPos(BlockPos renderPos) { + this.renderPos = renderPos; + return this; + } + public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { this.renderWorld = renderWorld; return this; @@ -49,7 +55,7 @@ public BakedModelWithDataBuilder withData(ModelData data) { @Override public void bufferInto(VertexConsumer consumer, ModelBlockRenderer blockRenderer, RandomSource random) { - blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY, data, null); + blockRenderer.tesselateBlock(renderWorld, model, referenceState, renderPos, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY, data, null); } public BlockModel toModel(String name) { diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java index ea7143d32..951578a66 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -17,6 +17,8 @@ public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFun builder.with(ModelUtil.VIRTUAL_PROPERTY, true); return new BakedModelWithDataBuilder(model) + .withRenderWorld(be.getLevel()) + .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) .withData(builder.build()) From b080c874b8d1ff125ee518d3f9fc2316bea2ef74 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 16:53:05 +0800 Subject: [PATCH 51/71] Forward block events for shafts on Forge --- .../functional/IFunctionalCopycatBlock.java | 15 +-- .../FunctionalCopycatBlockMixin.java | 107 ++++++++++++++++++ .../main/resources/copycats-forge.mixins.json | 1 + 3 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java index 2a13eb005..01434d51b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -1,14 +1,9 @@ package com.copycatsplus.copycats.content.copycat.base.functional; -import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; import com.simibubi.create.content.equipment.wrench.IWrenchable; -import com.simibubi.create.foundation.placement.IPlacementHelper; -import com.simibubi.create.foundation.placement.PlacementHelpers; -import com.simibubi.create.foundation.utility.Pair; import net.minecraft.client.Minecraft; import net.minecraft.client.color.block.BlockColor; import net.minecraft.core.BlockPos; @@ -22,14 +17,8 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.GrassColor; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.StairBlock; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java new file mode 100644 index 000000000..1a1b0101d --- /dev/null +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java @@ -0,0 +1,107 @@ +package com.copycatsplus.copycats.forge.mixin.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; +import com.simibubi.create.AllBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.HitResult; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; + +import static com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock.getMaterial; + +@Mixin(CopycatShaftBlock.class) +public abstract class FunctionalCopycatBlockMixin extends Block implements IFunctionalCopycatBlock { + + public FunctionalCopycatBlockMixin(Properties properties) { + super(properties); + } + + @Override + public SoundType getSoundType(BlockState state, LevelReader level, BlockPos pos, Entity entity) { + return getMaterial(level, pos).getSoundType(); + } + + @Override + public float getFriction(BlockState state, LevelReader level, BlockPos pos, Entity entity) { + return getMaterial(level, pos).getFriction(level, pos, entity); + } + + @Override + public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) { + return getMaterial(level, pos).getLightEmission(level, pos); + } + + @Override + public boolean canHarvestBlock(BlockState state, BlockGetter level, BlockPos pos, Player player) { + return getMaterial(level, pos).canHarvestBlock(level, pos, player); + } + + @Override + public float getExplosionResistance(BlockState state, BlockGetter level, BlockPos pos, Explosion explosion) { + return getMaterial(level, pos).getExplosionResistance(level, pos, explosion); + } + + @Override + public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos, + Player player) { + BlockState material = getMaterial(level, pos); + if (AllBlocks.COPYCAT_BASE.has(material) || player != null && player.isShiftKeyDown()) + return new ItemStack(this); + return material.getCloneItemStack(target, level, pos, player); + } + + @Override + public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos pos, BlockState state2, + LivingEntity entity, int numberOfParticles) { + return getMaterial(level, pos).addLandingEffects(level, pos, state2, entity, numberOfParticles); + } + + @Override + public boolean addRunningEffects(BlockState state, Level level, BlockPos pos, Entity entity) { + return getMaterial(level, pos).addRunningEffects(level, pos, entity); + } + + @Override + public float getEnchantPowerBonus(BlockState state, LevelReader level, BlockPos pos) { + return getMaterial(level, pos).getEnchantPowerBonus(level, pos); + } + + @Override + public boolean canEntityDestroy(BlockState state, BlockGetter level, BlockPos pos, Entity entity) { + return getMaterial(level, pos).canEntityDestroy(level, pos, entity); + } + + @Override + public boolean isValidSpawn(BlockState state, BlockGetter level, BlockPos pos, SpawnPlacements.Type type, + EntityType entityType) { + return false; + } + + @Override + public void fallOn(@NotNull Level pLevel, @NotNull BlockState pState, @NotNull BlockPos pPos, @NotNull Entity pEntity, float p_152430_) { + BlockState material = getMaterial(pLevel, pPos); + material.getBlock() + .fallOn(pLevel, material, pPos, pEntity, p_152430_); + } + + @SuppressWarnings("deprecation") + @Override + public float getDestroyProgress(@NotNull BlockState pState, @NotNull Player pPlayer, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos) { + return getMaterial(pLevel, pPos).getDestroyProgress(pPlayer, pLevel, pPos); + } +} diff --git a/forge/src/main/resources/copycats-forge.mixins.json b/forge/src/main/resources/copycats-forge.mixins.json index 47799b657..63ba03360 100644 --- a/forge/src/main/resources/copycats-forge.mixins.json +++ b/forge/src/main/resources/copycats-forge.mixins.json @@ -8,6 +8,7 @@ "compat.doubleslabs.DSConfigCommonMixin", "compat.registrate.CreateRegistrateMixin", "copycat.base.CopycatModelMixin", + "copycat.base.functional.FunctionalCopycatBlockMixin", "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin", "network.ServerGamePacketListenerImplMixin" ], From 2df4286c94975bd1917ad40992992a5f5f5147b3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 16:56:58 +0800 Subject: [PATCH 52/71] Disallow metal brackets in copycats --- .../java/com/copycatsplus/copycats/datagen/CCTagGen.java | 5 +++-- .../resources/data/create/tags/blocks/copycat_deny.json | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java b/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java index 219fa4366..68ff5dfe4 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java @@ -3,6 +3,7 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.compat.Mods; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.foundation.data.TagGen; import com.tterrag.registrate.providers.ProviderType; @@ -22,7 +23,7 @@ private static void genBlockTags(RegistrateTagsProvider provIn) { prov.tag(TagKey.create(BuiltInRegistries.BLOCK.key(), Mods.DIAGONAL_FENCES.rl("non_diagonal_fences"))) .add(CCBlocks.COPYCAT_FENCE.get()) .add(CCBlocks.WRAPPED_COPYCAT_FENCE.get()); -// prov.tag(AllTags.AllBlockTags.COPYCAT_DENY.tag) -// .addTag(AllTags.AllBlockTags.TRACKS.tag); + prov.tag(AllTags.AllBlockTags.COPYCAT_DENY.tag) + .add(AllBlocks.METAL_BRACKET.get()); } } diff --git a/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json b/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json new file mode 100644 index 000000000..d27cea405 --- /dev/null +++ b/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json @@ -0,0 +1,5 @@ +{ + "values": [ + "create:metal_bracket" + ] +} \ No newline at end of file From e7950b3202a1c4a1951ebec66f9b4af145ee1b15 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 18:19:17 +0800 Subject: [PATCH 53/71] WIP implementation of fabric rendering (not working yet) --- .../model/functional/WrappedRenderWorld.java | 143 +++++++++++++++++ .../shaft/CopycatShaftBlockEntity.java | 2 +- .../copycat/slab/CopycatSlabBlock.java | 7 +- .../copycats/blockstates/copycat_shaft.json | 7 + .../resources/assets/copycats/lang/en_ud.json | 1 + .../resources/assets/copycats/lang/en_us.json | 1 + .../copycats/models/item/copycat_shaft.json | 3 + .../misc/stonecutting/copycat_shaft.json | 33 ++++ .../loot_tables/blocks/copycat_shaft.json | 21 +++ .../recipes/stonecutting/copycat_shaft.json | 8 + .../data/create/tags/blocks/copycat_deny.json | 6 + .../minecraft/tags/blocks/mineable/axe.json | 3 +- .../tags/blocks/mineable/pickaxe.json | 3 +- .../fabric/BakedModelWithDataBuilder.java | 83 ++++++++++ .../FunctionalCopycatRenderHelperImpl.java | 17 ++ .../fabric/CopycatShaftBlockEntityFabric.java | 20 +++ .../shaft/fabric/CopycatShaftModelFabric.java | 42 +++++ .../fabric/CCBlockEntityTypesImpl.java | 6 + .../copycats/fabric/CCBlocksImpl.java | 6 + .../FunctionalCopycatBlockMixin.java | 146 ++++++++++++++++++ .../resources/copycats-fabric.mixins.json | 1 + .../forge/BakedModelWithDataBuilder.java | 11 +- 22 files changed, 560 insertions(+), 10 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java create mode 100644 fabric/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json create mode 100644 fabric/src/generated/resources/assets/copycats/models/item/copycat_shaft.json create mode 100644 fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json create mode 100644 fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json create mode 100644 fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json create mode 100644 fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftBlockEntityFabric.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java new file mode 100644 index 000000000..f400e90d1 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java @@ -0,0 +1,143 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional; + + +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.SectionPos; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.DataLayer; +import net.minecraft.world.level.chunk.LightChunk; +import net.minecraft.world.level.chunk.LightChunkGetter; +import net.minecraft.world.level.lighting.LayerLightEventListener; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class WrappedRenderWorld implements VirtualEmptyBlockGetter { + protected final BlockAndTintGetter level; + protected final LevelLightEngine lightEngine; + + public WrappedRenderWorld(BlockAndTintGetter level) { + this.level = level; + lightEngine = new LevelLightEngine(new LightChunkGetter() { + @Override + @Nullable + public LightChunk getChunkForLighting(int p_63023_, int p_63024_) { + return null; + } + + @Override + public @NotNull BlockGetter getLevel() { + return WrappedRenderWorld.this; + } + }, false, false) { + private final LayerLightEventListener blockListener = createStaticListener(15); + private final LayerLightEventListener skyListener = createStaticListener(15); + + @Override + public @NotNull LayerLightEventListener getLayerListener(@NotNull LightLayer layer) { + return layer == LightLayer.BLOCK ? blockListener : skyListener; + } + }; + } + + private static LayerLightEventListener createStaticListener(int light) { + return new LayerLightEventListener() { + @Override + public void checkBlock(@NotNull BlockPos pos) { + } + + @Override + public boolean hasLightWork() { + return false; + } + + @Override + public int runLightUpdates() { + return 0; + } + + @Override + public void updateSectionStatus(@NotNull SectionPos pos, boolean isSectionEmpty) { + } + + @Override + public void setLightEnabled(@NotNull ChunkPos pos, boolean lightEnabled) { + } + + @Override + public void propagateLightSources(@NotNull ChunkPos pos) { + } + + @Override + public DataLayer getDataLayerData(@NotNull SectionPos pos) { + return null; + } + + @Override + public int getLightValue(@NotNull BlockPos pos) { + return light; + } + }; + } + + @Override + @Nullable + public BlockEntity getBlockEntity(@NotNull BlockPos pos) { + return level.getBlockEntity(pos); + } + + @Override + public @NotNull BlockState getBlockState(@NotNull BlockPos pos) { + return level.getBlockState(pos); + } + + @Override + public @NotNull FluidState getFluidState(@NotNull BlockPos pos) { + return level.getFluidState(pos); + } + + @Override + public int getHeight() { + return level.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return level.getMinBuildHeight(); + } + + @Override + public float getShade(@NotNull Direction direction, boolean shaded) { + return level.getShade(direction, shaded); + } + + @Override + public @NotNull LevelLightEngine getLightEngine() { + return lightEngine; + } + + @Override + public int getBlockTint(@NotNull BlockPos pos, @NotNull ColorResolver resolver) { + return level.getBlockTint(pos, resolver); + } + + @Override + public int getBrightness(@NotNull LightLayer lightType, @NotNull BlockPos blockPos) { + return level.getBrightness(lightType, blockPos); + } + + @Override + public int getRawBrightness(@NotNull BlockPos blockPos, int amount) { + return level.getRawBrightness(blockPos, amount); + } + + @Override + public boolean canSeeSky(@NotNull BlockPos blockPos) { + return level.canSeeSky(blockPos); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java index 105e5a064..992a4d4e4 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlockEntity.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -public class CopycatShaftBlockEntity extends BracketedKineticBlockEntity implements IFunctionalCopycatBlockEntity { +public abstract class CopycatShaftBlockEntity extends BracketedKineticBlockEntity implements IFunctionalCopycatBlockEntity { protected CopycatBlockEntity copycatBlockEntity; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java index 7062ef06d..c3baafafb 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slab/CopycatSlabBlock.java @@ -3,6 +3,7 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.ICopycatWithWrappedBlock; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.copycatsplus.copycats.content.copycat.base.multistate.WaterloggedMultiStateCopycatBlock; @@ -283,12 +284,6 @@ public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState sta && getMaterial(level, pos).skipRendering(neighborState, dir.getOpposite()); } - public static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) { - BlockState state = CopycatBlock.getMaterial(reader, targetPos); - if (state.is(Blocks.AIR)) return reader.getBlockState(targetPos); - return state; - } - @Override public @NotNull BlockState rotate(@NotNull BlockState state, Rotation rot) { state = super.rotate(state, rot); diff --git a/fabric/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json new file mode 100644 index 000000000..2c8f02f06 --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/blockstates/copycat_shaft.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "minecraft:block/air" + } + } +} \ No newline at end of file diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json index b15de372a..40d6f1160 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_ud.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_ud.json @@ -81,6 +81,7 @@ "block.copycats.copycat_light_weighted_pressure_plate.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.condition1": "pǝʞɔıןƆ-ᴚ uǝɥM", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.summary": "˙ǝʇɐןd ǝɹnssǝɹd pǝʇɥbıǝʍ ʇɥbıן ןɐuoıʇɔunɟ ɐ oʇuı ‾ʞɔoןq ןןnɟ‾ ʎuɐ ‾sʇɹǝʌuoƆ‾", + "block.copycats.copycat_shaft": "ʇɟɐɥS ʇɐɔʎdoƆ", "block.copycats.copycat_slab": "qɐןS ʇɐɔʎdoƆ", "block.copycats.copycat_slab.tooltip.behaviour1": "˙ןɐıɹǝʇɐɯ ǝɥʇ ‾ʇǝsǝɹ‾ oʇ ‾ɥɔuǝɹM‾ ɐ ǝs∩ ˙ǝʇɐʇs ‾pǝɹǝʍod‾ ɹo ‾uoıʇɐʇuǝıɹo‾ ǝןɔʎɔ oʇ ‾uıɐbɐ ʞɔıןƆ‾ ˙ǝןqıssod ɟı ‾ןɐıɹǝʇɐɯ‾ sʇı sɐ ‾ɯǝʇı pןǝɥ‾ sǝıןddⱯ", "block.copycats.copycat_slab.tooltip.behaviour2": "˙‾ןɐıɹǝʇɐɯ‾ sʇı uo ‾sǝɹnʇxǝʇ pǝʇɔǝuuoɔ‾ sǝןbbo⟘", diff --git a/fabric/src/generated/resources/assets/copycats/lang/en_us.json b/fabric/src/generated/resources/assets/copycats/lang/en_us.json index 297e3a7a3..ed2c04a09 100644 --- a/fabric/src/generated/resources/assets/copycats/lang/en_us.json +++ b/fabric/src/generated/resources/assets/copycats/lang/en_us.json @@ -81,6 +81,7 @@ "block.copycats.copycat_light_weighted_pressure_plate.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.condition1": "When R-Clicked", "block.copycats.copycat_light_weighted_pressure_plate.tooltip.summary": "_Converts_ any _full block_ into a functional light weighted pressure plate.", + "block.copycats.copycat_shaft": "Copycat Shaft", "block.copycats.copycat_slab": "Copycat Slab", "block.copycats.copycat_slab.tooltip.behaviour1": "Applies _held item_ as its _material_ if possible. _Click again_ to cycle _orientation_ or _powered_ state. Use a _Wrench_ to _reset_ the material.", "block.copycats.copycat_slab.tooltip.behaviour2": "Toggles _connected textures_ on its _material_.", diff --git a/fabric/src/generated/resources/assets/copycats/models/item/copycat_shaft.json b/fabric/src/generated/resources/assets/copycats/models/item/copycat_shaft.json new file mode 100644 index 000000000..bd5cfb8df --- /dev/null +++ b/fabric/src/generated/resources/assets/copycats/models/item/copycat_shaft.json @@ -0,0 +1,3 @@ +{ + "parent": "copycats:block/copycat_base/shaft" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json new file mode 100644 index 000000000..783e485e0 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/advancements/recipes/misc/stonecutting/copycat_shaft.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_item": { + "conditions": { + "items": [ + { + "tag": "c:zinc_ingots" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "copycats:stonecutting/copycat_shaft" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "copycats:stonecutting/copycat_shaft" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json new file mode 100644 index 000000000..25139ab89 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/loot_tables/blocks/copycat_shaft.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "copycats:copycat_shaft" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "copycats:blocks/copycat_shaft" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json new file mode 100644 index 000000000..42c3d3ab6 --- /dev/null +++ b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:stonecutting", + "count": 2, + "ingredient": { + "tag": "c:zinc_ingots" + }, + "result": "copycats:copycat_shaft" +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json b/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json new file mode 100644 index 000000000..91b3d67f8 --- /dev/null +++ b/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "create:metal_bracket" + ] +} \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json index 69cd8d562..d5ff1997d 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_shaft" ] } \ No newline at end of file diff --git a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 69cd8d562..d5ff1997d 100644 --- a/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -26,6 +26,7 @@ "copycats:copycat_vertical_slice", "copycats:copycat_vertical_step", "copycats:copycat_wall", - "copycats:copycat_slope" + "copycats:copycat_slope", + "copycats:copycat_shaft" ] } \ No newline at end of file diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java new file mode 100644 index 000000000..9167ac585 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java @@ -0,0 +1,83 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional.fabric; + +import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; +import com.jozufozu.flywheel.core.model.BlockModel; +import com.jozufozu.flywheel.core.model.Bufferable; +import com.jozufozu.flywheel.core.model.ShadeSeparatingVertexConsumer; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.jozufozu.flywheel.fabric.model.DefaultLayerFilteringBakedModel; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class BakedModelWithDataBuilder implements Bufferable { + private final BakedModel model; + private BlockAndTintGetter renderWorld = VirtualEmptyBlockGetter.INSTANCE; + private BlockState referenceState = Blocks.AIR.defaultBlockState(); + private PoseStack poseStack = new PoseStack(); + private BlockPos renderPos = BlockPos.ZERO; + + public BakedModelWithDataBuilder(BakedModel model) { + this.model = model; + } + + public BakedModelWithDataBuilder withRenderPos(BlockPos renderPos) { + this.renderPos = renderPos; + return this; + } + + public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { + this.renderWorld = new WrappedRenderWorldFabric(renderWorld); + return this; + } + + public BakedModelWithDataBuilder withReferenceState(BlockState referenceState) { + this.referenceState = referenceState; + return this; + } + + public BakedModelWithDataBuilder withPoseStack(PoseStack poseStack) { + this.poseStack = poseStack; + return this; + } + + @Override + public void bufferInto(VertexConsumer consumer, ModelBlockRenderer blockRenderer, RandomSource random) { + BakedModel model = DefaultLayerFilteringBakedModel.wrap(this.model); + if (consumer instanceof ShadeSeparatingVertexConsumer shadeSeparatingWrapper) { + model = shadeSeparatingWrapper.wrapModel(model); + } + blockRenderer.tesselateBlock(renderWorld, model, referenceState, renderPos, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY); + } + + public BlockModel toModel(String name) { + return BlockModel.of(this, name); + } + + public BlockModel toModel() { + return toModel(referenceState.toString()); + } + + @SuppressWarnings("deprecation") + private static class WrappedRenderWorldFabric extends WrappedRenderWorld implements RenderAttachedBlockView { + public WrappedRenderWorldFabric(BlockAndTintGetter level) { + super(level); + } + + @Override + @Nullable + public Object getBlockEntityRenderAttachment(@NotNull BlockPos pos) { + return ((RenderAttachedBlockView) level).getBlockEntityRenderAttachment(pos); + } + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java new file mode 100644 index 000000000..b62964513 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java @@ -0,0 +1,17 @@ +package com.copycatsplus.copycats.content.copycat.base.model.functional.fabric; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.resources.model.BakedModel; + +public class FunctionalCopycatRenderHelperImpl { + public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { + return new BakedModelWithDataBuilder(model) + .withRenderWorld(be.getLevel()) + .withRenderPos(be.getBlockPos()) + .withReferenceState(be.getBlockState()) + .withPoseStack(ms) + .build(); + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftBlockEntityFabric.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftBlockEntityFabric.java new file mode 100644 index 000000000..71d6bbea3 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftBlockEntityFabric.java @@ -0,0 +1,20 @@ +package com.copycatsplus.copycats.content.copycat.shaft.fabric; + +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +public class CopycatShaftBlockEntityFabric extends CopycatShaftBlockEntity implements RenderAttachmentBlockEntity { + public CopycatShaftBlockEntityFabric(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + } + + @Override + public BlockState getRenderAttachmentData() { + return getMaterial(); + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java new file mode 100644 index 000000000..f70d8c8bd --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java @@ -0,0 +1,42 @@ +package com.copycatsplus.copycats.content.copycat.shaft.fabric; + +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockModel; +import io.github.fabricators_of_create.porting_lib.models.CustomParticleIconModel; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.function.Supplier; + +public class CopycatShaftModelFabric extends BracketedKineticBlockModel implements CustomParticleIconModel { + private final BakedModel copycat; + + public CopycatShaftModelFabric(BakedModel template, BakedModel copycat) { + super(template); + this.copycat = copycat; + } + + @Override + public boolean isVanillaAdapter() { + return false; + } + + @Override + public TextureAtlasSprite getParticleIcon(Object data) { + return ((CustomParticleIconModel) copycat).getParticleIcon(data); + } + + @Override + public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + if (!VirtualEmptyBlockGetter.is(blockView)) { + super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + } else { + copycat.emitBlockQuads(blockView, state, pos, randomSupplier, context); + } + } +} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlockEntityTypesImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlockEntityTypesImpl.java index 9b2b5b62d..38f03e7e5 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlockEntityTypesImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlockEntityTypesImpl.java @@ -4,6 +4,8 @@ import com.copycatsplus.copycats.content.copycat.base.multistate.fabric.MultiStateCopycatBlockEntityFabric; import com.copycatsplus.copycats.content.copycat.ladder.CopycatLadderMultiStateBlockEntity; import com.copycatsplus.copycats.content.copycat.ladder.fabric.CopycatLadderMultiStateBlockEntityFabric; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; +import com.copycatsplus.copycats.content.copycat.shaft.fabric.CopycatShaftBlockEntityFabric; import com.tterrag.registrate.builders.BlockEntityBuilder; public class CCBlockEntityTypesImpl { @@ -15,4 +17,8 @@ public static BlockEntityBuilder.BlockEntityFactory getPlatformMultiStateLadder() { return CopycatLadderMultiStateBlockEntityFabric::new; } + + public static BlockEntityBuilder.BlockEntityFactory getPlatformShaft() { + return CopycatShaftBlockEntityFabric::new; + } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlocksImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlocksImpl.java index 119c10c21..ee68c869d 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlocksImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/CCBlocksImpl.java @@ -1,7 +1,9 @@ package com.copycatsplus.copycats.fabric; +import com.copycatsplus.copycats.content.copycat.shaft.fabric.CopycatShaftModelFabric; import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.RegistrateBlockstateProvider; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.world.level.block.Block; public class CCBlocksImpl { @@ -9,4 +11,8 @@ public class CCBlocksImpl { public static void getWrappedBlockState(DataGenContext c, RegistrateBlockstateProvider p, String name) { p.simpleBlock(c.getEntry(), p.models().withExistingParent(name, "block/barrier")); } + + public static BakedModel getShaftModel(BakedModel original, BakedModel copycat) { + return new CopycatShaftModelFabric(original, copycat); + } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java new file mode 100644 index 000000000..6e1ef8ee5 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java @@ -0,0 +1,146 @@ +package com.copycatsplus.copycats.fabric.mixin.copycat.base.functional; + +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; +import com.simibubi.create.AllBlocks; +import io.github.fabricators_of_create.porting_lib.block.*; +import io.github.fabricators_of_create.porting_lib.enchant.EnchantmentBonusBlock; +import net.fabricmc.fabric.api.block.BlockPickInteractionAware; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.HitResult; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import javax.annotation.Nullable; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import static com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock.getMaterial; + +@Mixin(CopycatShaftBlock.class) +public abstract class FunctionalCopycatBlockMixin extends Block implements IFunctionalCopycatBlock, + CustomFrictionBlock, CustomSoundTypeBlock, LightEmissiveBlock, ExplosionResistanceBlock, + BlockPickInteractionAware, CustomLandingEffectsBlock, CustomRunningEffectsBlock, EnchantmentBonusBlock, + ValidSpawnBlock { + + public FunctionalCopycatBlockMixin(Properties properties) { + super(properties); + } + + @Override + public SoundType getSoundType(BlockState state, LevelReader level, BlockPos pos, Entity entity) { + return getMaterial(level, pos).getSoundType(); + } + + @Override + public float getFriction(BlockState state, LevelReader level, BlockPos pos, Entity entity) { + return maybeMaterialAs( + level, pos, CustomFrictionBlock.class, + (material, block) -> block.getFriction(material, level, pos, entity), + material -> material.getBlock().getFriction() + ); + } + + @Override + public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) { + return maybeMaterialAs( + level, pos, LightEmissiveBlock.class, + (material, block) -> block.getLightEmission(material, level, pos), + BlockStateBase::getLightEmission + ); + } + + @Override + public float getExplosionResistance(BlockState state, BlockGetter level, BlockPos pos, Explosion explosion) { + return maybeMaterialAs( + level, pos, ExplosionResistanceBlock.class, + (material, block) -> block.getExplosionResistance(material, level, pos, explosion), + material -> material.getBlock().getExplosionResistance() + ); + } + + @Override + public ItemStack getPickedStack(BlockState state, BlockGetter level, BlockPos pos, @Nullable Player player, @Nullable HitResult result) { + BlockState material = getMaterial(level, pos); + if (AllBlocks.COPYCAT_BASE.has(material) || player != null && player.isShiftKeyDown()) + return new ItemStack(this); + return maybeMaterialAs( + level, pos, BlockPickInteractionAware.class, + (mat, block) -> block.getPickedStack(mat, level, pos, player, result), + mat -> mat.getBlock().getCloneItemStack(level, pos, mat) + ); + } + + @Override + public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos pos, BlockState state2, + LivingEntity entity, int numberOfParticles) { + return maybeMaterialAs( + level, pos, CustomLandingEffectsBlock.class, // duplicate material is not a bug + (material, block) -> block.addLandingEffects(material, level, pos, material, entity, numberOfParticles), + material -> false // default to vanilla, true cancels + ); + } + + @Override + public boolean addRunningEffects(BlockState state, Level level, BlockPos pos, Entity entity) { + return maybeMaterialAs( + level, pos, CustomRunningEffectsBlock.class, + (material, block) -> block.addRunningEffects(material, level, pos, entity), + material -> false // default to vanilla, true cancels + ); + } + + @Override + public float getEnchantPowerBonus(BlockState state, LevelReader level, BlockPos pos) { + return maybeMaterialAs( + level, pos, EnchantmentBonusBlock.class, + (material, block) -> block.getEnchantPowerBonus(material, level, pos), + material -> EnchantmentBonusBlock.super.getEnchantPowerBonus(material, level, pos) + ); + } + + @Override + public boolean isValidSpawn(BlockState state, BlockGetter level, BlockPos pos, SpawnPlacements.Type type, + EntityType entityType) { + return false; + } + + @Override + public void fallOn(@NotNull Level pLevel, @NotNull BlockState pState, @NotNull BlockPos pPos, @NotNull Entity pEntity, float p_152430_) { + BlockState material = getMaterial(pLevel, pPos); + material.getBlock() + .fallOn(pLevel, material, pPos, pEntity, p_152430_); + } + + @SuppressWarnings("deprecation") + @Override + public float getDestroyProgress(@NotNull BlockState pState, @NotNull Player pPlayer, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos) { + return getMaterial(pLevel, pPos).getDestroyProgress(pPlayer, pLevel, pPos); + } + + @Unique + private static R maybeMaterialAs(BlockGetter level, BlockPos pos, Class clazz, + BiFunction ifType, Function ifNot) { + BlockState material = getMaterial(level, pos); + Block block = material.getBlock(); + if (clazz.isInstance(block)) + return ifType.apply(material, clazz.cast(block)); + return ifNot.apply(material); + } +} diff --git a/fabric/src/main/resources/copycats-fabric.mixins.json b/fabric/src/main/resources/copycats-fabric.mixins.json index 48253d7b3..511c72175 100644 --- a/fabric/src/main/resources/copycats-fabric.mixins.json +++ b/fabric/src/main/resources/copycats-fabric.mixins.json @@ -7,6 +7,7 @@ "mixins": [ "HolderReferenceInvoker", "compat.registrate.CreateRegistrateMixin", + "copycat.base.functional.FunctionalCopycatBlockMixin", "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin" ], "client": [ diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java index b647ac4b2..c0889f623 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional.forge; +import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; import com.jozufozu.flywheel.core.model.BlockModel; import com.jozufozu.flywheel.core.model.Bufferable; import com.jozufozu.flywheel.core.model.ModelUtil; @@ -10,11 +11,19 @@ import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.ColorResolver; +import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.FluidState; import net.minecraftforge.client.model.data.ModelData; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public final class BakedModelWithDataBuilder implements Bufferable { private final BakedModel model; @@ -34,7 +43,7 @@ public BakedModelWithDataBuilder withRenderPos(BlockPos renderPos) { } public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { - this.renderWorld = renderWorld; + this.renderWorld = new WrappedRenderWorld(renderWorld); return this; } From c543e3d9f1774007d76b2c489d774123c0ecbbfb Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 20:12:41 +0800 Subject: [PATCH 54/71] Fix model lighting for copycat shaft --- .../functional/IFunctionalCopycatBlock.java | 3 +- .../model/functional/WrappedRenderWorld.java | 36 +++++++++---------- .../fabric/BakedModelWithDataBuilder.java | 19 +--------- .../FunctionalCopycatRenderHelperImpl.java | 20 ++++++++++- .../forge/BakedModelWithDataBuilder.java | 11 +----- .../FunctionalCopycatRenderHelperImpl.java | 3 +- 6 files changed, 41 insertions(+), 51 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java index 01434d51b..7bb9f1c15 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -242,8 +242,7 @@ public int getColor(BlockState pState, @Nullable BlockAndTintGetter pLevel, @Nul int pTintIndex) { return Minecraft.getInstance() .getBlockColors() - // we don't want colors to change based on biome because we are caching the render result - .getColor(getMaterial(pLevel, pPos), pLevel, null, pTintIndex); + .getColor(getMaterial(pLevel, pPos), pLevel, pPos, pTintIndex); } } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java index f400e90d1..af4c65d94 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java @@ -1,11 +1,17 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.SectionPos; +import net.minecraft.core.registries.Registries; import net.minecraft.world.level.*; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.DataLayer; @@ -14,15 +20,18 @@ import net.minecraft.world.level.lighting.LayerLightEventListener; import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class WrappedRenderWorld implements VirtualEmptyBlockGetter { protected final BlockAndTintGetter level; + protected final BlockPos targetPos; protected final LevelLightEngine lightEngine; - public WrappedRenderWorld(BlockAndTintGetter level) { - this.level = level; + public WrappedRenderWorld(IFunctionalCopycatBlockEntity be) { + this.level = be.getLevel(); + this.targetPos = be.getBlockPos(); lightEngine = new LevelLightEngine(new LightChunkGetter() { @Override @Nullable @@ -88,16 +97,19 @@ public int getLightValue(@NotNull BlockPos pos) { @Override @Nullable public BlockEntity getBlockEntity(@NotNull BlockPos pos) { + if (!pos.equals(targetPos)) return null; return level.getBlockEntity(pos); } @Override public @NotNull BlockState getBlockState(@NotNull BlockPos pos) { + if (!pos.equals(targetPos)) return Blocks.AIR.defaultBlockState(); return level.getBlockState(pos); } @Override public @NotNull FluidState getFluidState(@NotNull BlockPos pos) { + if (!pos.equals(targetPos)) return Fluids.EMPTY.defaultFluidState(); return level.getFluidState(pos); } @@ -113,7 +125,7 @@ public int getMinBuildHeight() { @Override public float getShade(@NotNull Direction direction, boolean shaded) { - return level.getShade(direction, shaded); + return 1f; } @Override @@ -123,21 +135,7 @@ public float getShade(@NotNull Direction direction, boolean shaded) { @Override public int getBlockTint(@NotNull BlockPos pos, @NotNull ColorResolver resolver) { - return level.getBlockTint(pos, resolver); - } - - @Override - public int getBrightness(@NotNull LightLayer lightType, @NotNull BlockPos blockPos) { - return level.getBrightness(lightType, blockPos); - } - - @Override - public int getRawBrightness(@NotNull BlockPos blockPos, int amount) { - return level.getRawBrightness(blockPos, amount); - } - - @Override - public boolean canSeeSky(@NotNull BlockPos blockPos) { - return level.canSeeSky(blockPos); + Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS); + return resolver.getColor(plainsBiome, pos.getX(), pos.getZ()); } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java index 9167ac585..86b893e68 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java @@ -1,6 +1,5 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional.fabric; -import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; import com.jozufozu.flywheel.core.model.BlockModel; import com.jozufozu.flywheel.core.model.Bufferable; import com.jozufozu.flywheel.core.model.ShadeSeparatingVertexConsumer; @@ -8,7 +7,6 @@ import com.jozufozu.flywheel.fabric.model.DefaultLayerFilteringBakedModel; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; @@ -17,8 +15,6 @@ import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public final class BakedModelWithDataBuilder implements Bufferable { private final BakedModel model; @@ -37,7 +33,7 @@ public BakedModelWithDataBuilder withRenderPos(BlockPos renderPos) { } public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { - this.renderWorld = new WrappedRenderWorldFabric(renderWorld); + this.renderWorld = renderWorld; return this; } @@ -67,17 +63,4 @@ public BlockModel toModel(String name) { public BlockModel toModel() { return toModel(referenceState.toString()); } - - @SuppressWarnings("deprecation") - private static class WrappedRenderWorldFabric extends WrappedRenderWorld implements RenderAttachedBlockView { - public WrappedRenderWorldFabric(BlockAndTintGetter level) { - super(level); - } - - @Override - @Nullable - public Object getBlockEntityRenderAttachment(@NotNull BlockPos pos) { - return ((RenderAttachedBlockView) level).getBlockEntityRenderAttachment(pos); - } - } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java index b62964513..d8f413591 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java @@ -1,17 +1,35 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional.fabric; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; import com.mojang.blaze3d.vertex.PoseStack; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class FunctionalCopycatRenderHelperImpl { public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { return new BakedModelWithDataBuilder(model) - .withRenderWorld(be.getLevel()) + .withRenderWorld(new WrappedRenderWorldFabric(be)) .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) .build(); } + + @SuppressWarnings("deprecation") + private static class WrappedRenderWorldFabric extends WrappedRenderWorld implements RenderAttachedBlockView { + public WrappedRenderWorldFabric(IFunctionalCopycatBlockEntity be) { + super(be); + } + + @Override + @Nullable + public Object getBlockEntityRenderAttachment(@NotNull BlockPos pos) { + return ((RenderAttachedBlockView) level).getBlockEntityRenderAttachment(pos); + } + } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java index c0889f623..b647ac4b2 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/BakedModelWithDataBuilder.java @@ -1,6 +1,5 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional.forge; -import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; import com.jozufozu.flywheel.core.model.BlockModel; import com.jozufozu.flywheel.core.model.Bufferable; import com.jozufozu.flywheel.core.model.ModelUtil; @@ -11,19 +10,11 @@ import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.ColorResolver; -import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.lighting.LevelLightEngine; -import net.minecraft.world.level.material.FluidState; import net.minecraftforge.client.model.data.ModelData; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public final class BakedModelWithDataBuilder implements Bufferable { private final BakedModel model; @@ -43,7 +34,7 @@ public BakedModelWithDataBuilder withRenderPos(BlockPos renderPos) { } public BakedModelWithDataBuilder withRenderWorld(BlockAndTintGetter renderWorld) { - this.renderWorld = new WrappedRenderWorld(renderWorld); + this.renderWorld = renderWorld; return this; } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java index 951578a66..2e3ab6966 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional.forge; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.model.functional.WrappedRenderWorld; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; import com.mojang.blaze3d.vertex.PoseStack; @@ -17,7 +18,7 @@ public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFun builder.with(ModelUtil.VIRTUAL_PROPERTY, true); return new BakedModelWithDataBuilder(model) - .withRenderWorld(be.getLevel()) + .withRenderWorld(new WrappedRenderWorld(be)) .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) From e6090b63333fbd6e4106ac790a905dec133b018e Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 21:23:52 +0800 Subject: [PATCH 55/71] Fix invisible render on fabric --- .../base/model/functional/fabric/BakedModelWithDataBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java index 86b893e68..54c8dd913 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/BakedModelWithDataBuilder.java @@ -49,7 +49,7 @@ public BakedModelWithDataBuilder withPoseStack(PoseStack poseStack) { @Override public void bufferInto(VertexConsumer consumer, ModelBlockRenderer blockRenderer, RandomSource random) { - BakedModel model = DefaultLayerFilteringBakedModel.wrap(this.model); + BakedModel model = this.model; //DefaultLayerFilteringBakedModel.wrap(this.model); // not sure what the goal of this filter is, but it filtered out all copycat quads if (consumer instanceof ShadeSeparatingVertexConsumer shadeSeparatingWrapper) { model = shadeSeparatingWrapper.wrapModel(model); } From 0c900beba7bcdfa5171bff41b0da24a7dd7514c4 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 21:56:48 +0800 Subject: [PATCH 56/71] Workaround for a potential flywheel bug --- .../IFunctionalCopycatBlockInstance.java | 22 ++++++++++++++++++- .../copycat/shaft/CopycatShaftInstance.java | 9 +++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java index 0da2e4059..420496fed 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java @@ -3,7 +3,14 @@ import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; +import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.RenderLayer; +import com.jozufozu.flywheel.config.BackendType; import com.simibubi.create.content.kinetics.base.flwdata.RotatingData; +import com.simibubi.create.foundation.render.AllMaterialSpecs; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; import javax.annotation.Nullable; @@ -12,11 +19,24 @@ public interface IFunctionalCopycatBlockInstance { @Nullable KineticCopycatRenderData getRenderData(); + MaterialManager getMaterialManager(); + void setRenderData(KineticCopycatRenderData renderData); IFunctionalCopycatBlockEntity getBlockEntity(); - Material getRotatingMaterial(); + default Material getRotatingMaterial() { + RenderType type = ItemBlockRenderTypes.getChunkRenderType(getRenderData().material()); + RenderLayer layer = RenderLayer.getLayer(type); + if (layer == null) layer = RenderLayer.TRANSPARENT; + + // workaround for flywheel crash when transparent layer is used in batching backend + if (Backend.getBackendType() == BackendType.BATCHING && type == RenderType.translucent()) + type = RenderType.cutoutMipped(); + + return getMaterialManager().state(layer, type) + .material(AllMaterialSpecs.ROTATING); + } default Instancer getModel() { KineticCopycatRenderData renderData = KineticCopycatRenderData.of(getBlockEntity()); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java index 0197bb888..da185e980 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftInstance.java @@ -9,7 +9,6 @@ import com.simibubi.create.content.kinetics.base.flwdata.RotatingData; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance; -import com.simibubi.create.foundation.render.AllMaterialSpecs; public class CopycatShaftInstance extends BracketedKineticBlockEntityInstance implements IFunctionalCopycatBlockInstance { protected KineticCopycatRenderData renderData; @@ -23,6 +22,11 @@ public KineticCopycatRenderData getRenderData() { return renderData; } + @Override + public MaterialManager getMaterialManager() { + return materialManager; + } + @Override public void setRenderData(KineticCopycatRenderData renderData) { this.renderData = renderData; @@ -35,8 +39,7 @@ public IFunctionalCopycatBlockEntity getBlockEntity() { @Override public Material getRotatingMaterial() { - return materialManager.defaultTransparent() - .material(AllMaterialSpecs.ROTATING); + return IFunctionalCopycatBlockInstance.super.getRotatingMaterial(); } @Override From 5609f8f1f569796e4502bbd32b548c3ff71df94a Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 23:28:32 +0800 Subject: [PATCH 57/71] Revert "Disallow metal brackets in copycats" This reverts commit 2df4286c94975bd1917ad40992992a5f5f5147b3. --- .../java/com/copycatsplus/copycats/datagen/CCTagGen.java | 5 ++--- .../resources/data/create/tags/blocks/copycat_deny.json | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java b/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java index 68ff5dfe4..219fa4366 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/CCTagGen.java @@ -3,7 +3,6 @@ import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.Copycats; import com.copycatsplus.copycats.compat.Mods; -import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.foundation.data.TagGen; import com.tterrag.registrate.providers.ProviderType; @@ -23,7 +22,7 @@ private static void genBlockTags(RegistrateTagsProvider provIn) { prov.tag(TagKey.create(BuiltInRegistries.BLOCK.key(), Mods.DIAGONAL_FENCES.rl("non_diagonal_fences"))) .add(CCBlocks.COPYCAT_FENCE.get()) .add(CCBlocks.WRAPPED_COPYCAT_FENCE.get()); - prov.tag(AllTags.AllBlockTags.COPYCAT_DENY.tag) - .add(AllBlocks.METAL_BRACKET.get()); +// prov.tag(AllTags.AllBlockTags.COPYCAT_DENY.tag) +// .addTag(AllTags.AllBlockTags.TRACKS.tag); } } diff --git a/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json b/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json deleted file mode 100644 index d27cea405..000000000 --- a/forge/src/generated/resources/data/create/tags/blocks/copycat_deny.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "values": [ - "create:metal_bracket" - ] -} \ No newline at end of file From e87c5c87ea8cd682edbc3683771b445e988f625c Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Tue, 25 Jun 2024 23:32:19 +0800 Subject: [PATCH 58/71] Specifically disallow brackets in copycat shafts because they should be installed around the shafts instead --- .../content/copycat/shaft/CopycatShaftBlock.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java index 37e4c087b..7c51a301a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java @@ -2,11 +2,13 @@ import com.copycatsplus.copycats.CCBlockEntityTypes; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.simibubi.create.content.decoration.bracket.BracketBlock; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; import com.simibubi.create.foundation.placement.IPlacementHelper; import com.simibubi.create.foundation.placement.PlacementHelpers; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; @@ -18,6 +20,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; +import org.jetbrains.annotations.Nullable; public class CopycatShaftBlock extends ShaftBlock implements IFunctionalCopycatBlock { @@ -62,6 +65,16 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player return super.use(state, world, pos, player, hand, ray); } + @Nullable + @Override + public BlockState getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack item, Direction face) { + if (item.getItem() instanceof BlockItem bi) { + if (bi.getBlock() instanceof BracketBlock) return null; + } + + return IFunctionalCopycatBlock.super.getAcceptedBlockState(pLevel, pPos, item, face); + } + @Override public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { super.setPlacedBy(worldIn, pos, state, placer, stack); From 1b6b50831706bfc16cc9f80b15f769ca62c28628 Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Wed, 26 Jun 2024 04:05:25 +0100 Subject: [PATCH 59/71] Add shape stuff to make the slopes hitboxes match the visual --- .../com/copycatsplus/copycats/CCShapes.java | 2 + .../copycat/slope/CopycatSlopeBlock.java | 70 +++++++++++++++-- .../mixin/copycat/VoxelShapeAccessor.java | 27 +++++++ .../utility/shape/ExtensibleVoxelShape.java | 21 ++++++ .../utility/shape/NoneVoxelShape.java | 46 ++++++++++++ .../utility/shape/VoxelCollection.java | 75 +++++++++++++++++++ .../copycats/utility/shape/VoxelUtils.java | 38 ++++++++++ .../resources/copycats-common.mixins.json | 1 + 8 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/mixin/copycat/VoxelShapeAccessor.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/utility/shape/ExtensibleVoxelShape.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/utility/shape/NoneVoxelShape.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelCollection.java create mode 100644 common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelUtils.java diff --git a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java index 8e4a47f1a..6ec740a96 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCShapes.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCShapes.java @@ -1,5 +1,7 @@ package com.copycatsplus.copycats; +import com.copycatsplus.copycats.utility.shape.NoneVoxelShape; +import com.copycatsplus.copycats.utility.shape.VoxelUtils; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.core.Direction; diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java index 1650c5089..b0fdf801b 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/slope/CopycatSlopeBlock.java @@ -4,6 +4,9 @@ import com.copycatsplus.copycats.CCShapes; import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.IStateType; +import com.copycatsplus.copycats.utility.shape.NoneVoxelShape; +import com.copycatsplus.copycats.utility.shape.VoxelCollection; +import com.copycatsplus.copycats.utility.shape.VoxelUtils; import com.simibubi.create.content.equipment.extendoGrip.ExtendoGripItem; import com.simibubi.create.foundation.placement.IPlacementHelper; import com.simibubi.create.foundation.placement.PlacementHelpers; @@ -35,12 +38,11 @@ import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.*; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.List; import java.util.function.Predicate; @@ -157,7 +159,65 @@ protected void createBlockStateDefinition(StateDefinition.Builder new Vec3[]{ + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 1 : 0), 0), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 1 : 0), 1) + }; + case EAST -> new Vec3[]{ + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 1 : 0), 1), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 1 : 0), 0) + }; + case NORTH -> new Vec3[]{ + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 1 : 0), 0), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 1 : 0), 0) + }; + case SOUTH -> new Vec3[]{ + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 0 : 1), 1), + new Vec3(1, (isBottom ? 0 : 1), 0), + new Vec3(1, (isBottom ? 1 : 0), 1), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 0 : 1), 1), + new Vec3(0, (isBottom ? 0 : 1), 0), + new Vec3(0, (isBottom ? 1 : 0), 1) + }; + default -> throw new AssertionError("Direction shouldn't appear as this is a horizontal facing block only"); + }; + + Vec3[] shape = VoxelUtils.create12Edges(triangleVertices); + + //Accidentally made a corner version +/* new Vec3(0.0, (isBottom ? 0 : 1), -0.0), + new Vec3(0.0, (isBottom ? 0 : 1), -0.0), + new Vec3(0.0, (isBottom ? 0 : 1), -1), + new Vec3(1, (isBottom ? 1 : 0), 0), + new Vec3(1, (isBottom ? 0 : 1), -0.0), + new Vec3(1, (isBottom ? 0 : 1), -0.0), + new Vec3(1, (isBottom ? 0 : 1), -1), + new Vec3(1, (isBottom ? 1 : 0), 0)*/ + + return new NoneVoxelShape((isBottom ? CCShapes.SLOPE_BOTTOM.get(facing) : CCShapes.SLOPE_TOP.get(facing)), shape); } diff --git a/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/VoxelShapeAccessor.java b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/VoxelShapeAccessor.java new file mode 100644 index 000000000..2b1aff909 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/mixin/copycat/VoxelShapeAccessor.java @@ -0,0 +1,27 @@ +package com.copycatsplus.copycats.mixin.copycat; + +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.shapes.DiscreteVoxelShape; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +/* + * Copied from https://github.com/Fuzss/diagonalblocks + */ +@Mixin(VoxelShape.class) +public interface VoxelShapeAccessor { + + @Accessor("shape") + DiscreteVoxelShape copycats$getShape(); + + @Accessor("shape") + @Mutable + void copycats$setShape(DiscreteVoxelShape shape); + + @Invoker("getCoords") + DoubleList copycats$callGetCoords(Direction.Axis axis); +} diff --git a/common/src/main/java/com/copycatsplus/copycats/utility/shape/ExtensibleVoxelShape.java b/common/src/main/java/com/copycatsplus/copycats/utility/shape/ExtensibleVoxelShape.java new file mode 100644 index 000000000..3b9ca6f90 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/utility/shape/ExtensibleVoxelShape.java @@ -0,0 +1,21 @@ +package com.copycatsplus.copycats.utility.shape; + +import com.copycatsplus.copycats.mixin.copycat.VoxelShapeAccessor; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.shapes.SliceShape; +import net.minecraft.world.phys.shapes.VoxelShape; + +/* + * Copied from https://github.com/Fuzss/diagonalblocks + */ +public abstract class ExtensibleVoxelShape extends SliceShape { + + public ExtensibleVoxelShape(VoxelShape voxelProvider) { + super(voxelProvider, Direction.Axis.X, 0); + ((VoxelShapeAccessor) this).copycats$setShape(((VoxelShapeAccessor) voxelProvider).copycats$getShape()); + } + + @Override + protected abstract DoubleList getCoords(Direction.Axis axis); +} diff --git a/common/src/main/java/com/copycatsplus/copycats/utility/shape/NoneVoxelShape.java b/common/src/main/java/com/copycatsplus/copycats/utility/shape/NoneVoxelShape.java new file mode 100644 index 000000000..7ea5209a1 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/utility/shape/NoneVoxelShape.java @@ -0,0 +1,46 @@ +package com.copycatsplus.copycats.utility.shape; + +import com.copycatsplus.copycats.mixin.copycat.VoxelShapeAccessor; +import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import java.util.List; + +/* + * Copied from https://github.com/Fuzss/diagonalblocks + */ +public class NoneVoxelShape extends ExtensibleVoxelShape { + private final VoxelShape collisionShape; + private final List outlineShapeEdges; + + public NoneVoxelShape(VoxelShape collisionShape, Vec3... outlineShapeEdges) { + super(collisionShape); + this.collisionShape = collisionShape; + this.outlineShapeEdges = this.createOutlineList(outlineShapeEdges); + } + + private List createOutlineList(Vec3[] outlineShapeEdges) { + if (outlineShapeEdges.length % 2 != 0) throw new IllegalStateException("Edges must be in groups of two points"); + List list = Lists.newArrayList(); + for (int i = 0; i < outlineShapeEdges.length; i += 2) { + list.add(new Vec3[]{outlineShapeEdges[i], outlineShapeEdges[i + 1]}); + } + return list; + } + + @Override + protected DoubleList getCoords(Direction.Axis axis) { + return ((VoxelShapeAccessor) this.collisionShape).copycats$callGetCoords(axis); + } + + @Override + public void forAllEdges(Shapes.DoubleLineConsumer boxConsumer) { + for (Vec3[] edge : this.outlineShapeEdges) { + boxConsumer.consume(edge[0].x, edge[0].y, edge[0].z, edge[1].x, edge[1].y, edge[1].z); + } + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelCollection.java b/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelCollection.java new file mode 100644 index 000000000..4f783744f --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelCollection.java @@ -0,0 +1,75 @@ +package com.copycatsplus.copycats.utility.shape; + +import com.copycatsplus.copycats.mixin.copycat.VoxelShapeAccessor; +import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import net.minecraft.core.Direction; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +import java.util.List; + +/* + * Copied from https://github.com/Fuzss/diagonalblocks + */ +public class VoxelCollection extends ExtensibleVoxelShape { + private VoxelShape collisionShape; + private VoxelShape outlineShape; + private VoxelShape particleShape; + private final List noneVoxels = Lists.newArrayList(); + + public VoxelCollection(VoxelShape baseShape) { + this(baseShape, baseShape); + } + + public VoxelCollection(VoxelShape baseShape, VoxelShape outlineBaseShape) { + super(baseShape); + this.collisionShape = baseShape; + this.outlineShape = outlineBaseShape; + this.particleShape = baseShape; + } + + @Override + protected DoubleList getCoords(Direction.Axis axis) { + return ((VoxelShapeAccessor) this.collisionShape).copycats$callGetCoords(axis); + } + + private void setCollisionShape(VoxelShape voxelShape) { + this.collisionShape = voxelShape; + ((VoxelShapeAccessor) this).copycats$setShape(((VoxelShapeAccessor) this.collisionShape).copycats$getShape()); + } + + public void addVoxelShape(VoxelShape voxelShape, VoxelShape particleShape) { + if (voxelShape instanceof NoneVoxelShape) { + this.addNoneVoxelShape((NoneVoxelShape) voxelShape); + } else { + this.setCollisionShape(Shapes.joinUnoptimized(this.collisionShape, voxelShape, BooleanOp.OR)); + this.outlineShape = Shapes.joinUnoptimized(this.outlineShape, voxelShape, BooleanOp.OR); + } + this.particleShape = Shapes.joinUnoptimized(this.particleShape, particleShape, BooleanOp.OR); + } + + private void addNoneVoxelShape(NoneVoxelShape voxelShape) { + this.noneVoxels.add(voxelShape); + this.setCollisionShape(Shapes.joinUnoptimized(this.collisionShape, voxelShape, BooleanOp.OR)); + } + + @Override + public VoxelCollection optimize() { + this.setCollisionShape(this.collisionShape.optimize()); + this.outlineShape = this.outlineShape.optimize(); + this.particleShape = this.particleShape.optimize(); + return this; + } + + public void forAllParticleBoxes(Shapes.DoubleLineConsumer doubleLineConsumer) { + this.particleShape.forAllBoxes(doubleLineConsumer); + } + + @Override + public void forAllEdges(Shapes.DoubleLineConsumer boxConsumer) { + this.outlineShape.forAllEdges(boxConsumer); + this.noneVoxels.forEach(voxelShape -> voxelShape.forAllEdges(boxConsumer)); + } +} diff --git a/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelUtils.java b/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelUtils.java new file mode 100644 index 000000000..aef07df47 --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/utility/shape/VoxelUtils.java @@ -0,0 +1,38 @@ +package com.copycatsplus.copycats.utility.shape; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.VoxelShape; + +import java.util.stream.Stream; + +/* +* Methods needed/wanted copied from https://github.com/Fuzss/diagonalblocks +*/ +public class VoxelUtils { + /** + * @param corners provided edges as top left, top right, bottom left and bottom right + * @return vectors as pairs representing the edges + */ + public static Vec3[] create12Edges(Vec3[] corners) { + if (corners.length != 8) throw new IllegalStateException("Amount of corners must be 8"); + return new Vec3[]{ + // skew side + corners[0], corners[1], + corners[1], corners[3], + corners[3], corners[2], + corners[2], corners[0], + // connections between skew sides + corners[0], corners[4], + corners[1], corners[5], + corners[2], corners[6], + corners[3], corners[7], + // other skew side + corners[4], corners[5], + corners[5], corners[7], + corners[7], corners[6], + corners[6], corners[4] + }; + } +} + diff --git a/common/src/main/resources/copycats-common.mixins.json b/common/src/main/resources/copycats-common.mixins.json index 5d2890499..8f524da4b 100644 --- a/common/src/main/resources/copycats-common.mixins.json +++ b/common/src/main/resources/copycats-common.mixins.json @@ -12,6 +12,7 @@ "compat.rubidium.BlockOcclusionCacheMixin", "compat.rubidium.BlockRendererMixin", "copycat.TrackPlacementMixin", + "copycat.VoxelShapeAccessor", "copycat.base.ConnectedTextureBehaviourMixin", "copycat.base.CopycatBlockEntityMixin", "copycat.base.CopycatBlockMixin", From a7af2f3f0f1e282a46036dabeed86d55d9ca5bd3 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 11:42:25 +0800 Subject: [PATCH 60/71] Allow static CT for functional copycats --- .../functional/IFunctionalCopycatBlock.java | 21 ++ .../model/functional/WrappedRenderWorld.java | 4 +- .../copycat/shaft/CopycatShaftBlock.java | 32 ++- .../base/model/fabric/CopycatModel.java | 184 ++++++++++++++++++ .../base/model/fabric/SimpleCopycatModel.java | 1 - .../fabric/ToggleableCopycatModelImpl.java | 1 - .../fabric/MultiStateCopycatModel.java | 67 +------ .../mixin/copycat/base/CopycatModelMixin.java | 41 ---- .../FunctionalCopycatBlockMixin.java | 18 +- .../resources/copycats-fabric.mixins.json | 1 - .../base/model/forge/CopycatModel.java | 175 +++++++++++++++++ .../base/model/forge/SimpleCopycatModel.java | 3 +- .../forge/ToggleableCopycatModelImpl.java | 6 +- .../FunctionalCopycatRenderHelperImpl.java | 5 +- .../forge/MultiStateCopycatModel.java | 19 +- .../forge/CopycatShaftBlockEntityForge.java | 12 -- .../copycat/base/CopycatModelAccessor.java | 20 -- .../mixin/copycat/base/CopycatModelMixin.java | 27 --- .../FunctionalCopycatBlockMixin.java | 15 +- .../main/resources/copycats-forge.mixins.json | 2 - 20 files changed, 448 insertions(+), 206 deletions(-) create mode 100644 fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/CopycatModel.java delete mode 100644 fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java create mode 100644 forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/CopycatModel.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelAccessor.java delete mode 100644 forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelMixin.java diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java index 7bb9f1c15..93345c198 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/functional/IFunctionalCopycatBlock.java @@ -1,8 +1,10 @@ package com.copycatsplus.copycats.content.copycat.base.functional; +import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags; import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatModel; import com.simibubi.create.content.equipment.wrench.IWrenchable; import net.minecraft.client.Minecraft; import net.minecraft.client.color.block.BlockColor; @@ -27,6 +29,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import javax.annotation.Nullable; +import java.util.Optional; /** * Indicates that a block functions as a copycat but is not a subclass of {@link CopycatBlock}. @@ -231,6 +234,24 @@ static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) { return Blocks.AIR.defaultBlockState(); } + default boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, + BlockPos fromPos, BlockPos toPos) { + return false; + } + + default boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, + BlockState state) { + return true; + } + + default boolean canFaceBeOccluded(BlockState state, Direction face) { + return false; + } + + default boolean shouldFaceAlwaysRender(BlockState state, Direction face) { + return false; + } + static BlockColor wrappedColor() { return new WrappedBlockColor(); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java index af4c65d94..4b4362d90 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java @@ -28,10 +28,12 @@ public class WrappedRenderWorld implements VirtualEmptyBlockGetter { protected final BlockAndTintGetter level; protected final BlockPos targetPos; protected final LevelLightEngine lightEngine; + protected final BlockState material; public WrappedRenderWorld(IFunctionalCopycatBlockEntity be) { this.level = be.getLevel(); this.targetPos = be.getBlockPos(); + this.material = be.getMaterial(); lightEngine = new LevelLightEngine(new LightChunkGetter() { @Override @Nullable @@ -103,7 +105,7 @@ public BlockEntity getBlockEntity(@NotNull BlockPos pos) { @Override public @NotNull BlockState getBlockState(@NotNull BlockPos pos) { - if (!pos.equals(targetPos)) return Blocks.AIR.defaultBlockState(); + if (!pos.equals(targetPos)) return material; return level.getBlockState(pos); } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java index 7c51a301a..35ad283b4 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.shaft; import com.copycatsplus.copycats.CCBlockEntityTypes; +import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.simibubi.create.content.decoration.bracket.BracketBlock; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; @@ -9,6 +10,7 @@ import com.simibubi.create.foundation.placement.PlacementHelpers; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.LivingEntity; @@ -20,9 +22,12 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CopycatShaftBlock extends ShaftBlock implements IFunctionalCopycatBlock { +import java.util.Optional; + +public class CopycatShaftBlock extends ShaftBlock implements IFunctionalCopycatBlock, ICustomCTBlocking { public CopycatShaftBlock(Properties properties) { super(properties); @@ -88,7 +93,7 @@ public void onRemove(BlockState state, Level world, BlockPos pos, BlockState new } @Override - public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { + public void playerWillDestroy(@NotNull Level level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull Player player) { super.playerWillDestroy(level, pos, state, player); IFunctionalCopycatBlock.super.playerWillDestroy(level, pos, state, player); } @@ -97,4 +102,27 @@ public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Playe public BlockEntityType getBlockEntityType() { return CCBlockEntityTypes.COPYCAT_SHAFT.get(); } + + @Override + public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { + return true; + } + + @Override + public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, BlockState state) { + Vec3i diff = toPos.subtract(fromPos); + Direction face = Direction.fromDelta(diff.getX(), diff.getY(), diff.getZ()); + if (face == null) return false; + return face.getAxis() == state.getValue(AXIS); + } + + @Override + public Optional blockCTTowards(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos ctPos, BlockPos connectingPos, Direction face) { + return Optional.of(false); + } + + @Override + public Optional isCTBlocked(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos connectingPos, BlockPos blockingPos, Direction face) { + return Optional.of(false); + } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/CopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/CopycatModel.java new file mode 100644 index 000000000..e09514a75 --- /dev/null +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/CopycatModel.java @@ -0,0 +1,184 @@ +package com.copycatsplus.copycats.content.copycat.base.model.fabric; + + +import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; +import com.simibubi.create.foundation.utility.Iterate; +import io.github.fabricators_of_create.porting_lib.models.CustomParticleIconModel; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +import javax.annotation.Nullable; +import java.util.Objects; +import java.util.function.Supplier; + +public abstract class CopycatModel extends ForwardingBakedModel implements CustomParticleIconModel { + + public CopycatModel(BakedModel originalModel) { + wrapped = originalModel; + } + + private void gatherOcclusionData(BlockAndTintGetter world, BlockPos pos, BlockState state, BlockState material, + OcclusionData occlusionData, IFunctionalCopycatBlock copycatBlock) { + BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + for (Direction face : Iterate.directions) { + if (!copycatBlock.canFaceBeOccluded(state, face)) + continue; + BlockPos.MutableBlockPos neighbourPos = mutablePos.setWithOffset(pos, face); + if (!Block.shouldRenderFace(material, world, pos, face, neighbourPos)) + occlusionData.occlude(face); + } + } + + @Override + public boolean isVanillaAdapter() { + return false; + } + + @SuppressWarnings("deprecation") + @Override + public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + BlockState material; + if (blockView instanceof RenderAttachedBlockView attachmentView + && attachmentView.getBlockEntityRenderAttachment(pos) instanceof BlockState material1) { + material = material1; + } else { + material = AllBlocks.COPYCAT_BASE.getDefaultState(); + } + + OcclusionData occlusionData = new OcclusionData(); + if (state.getBlock() instanceof IFunctionalCopycatBlock copycatBlock) { + gatherOcclusionData(blockView, pos, state, material, occlusionData, copycatBlock); + } + + CullFaceRemovalData cullFaceRemovalData = new CullFaceRemovalData(); + if (state.getBlock() instanceof IFunctionalCopycatBlock copycatBlock) { + for (Direction cullFace : Iterate.directions) { + if (copycatBlock.shouldFaceAlwaysRender(state, cullFace)) { + cullFaceRemovalData.remove(cullFace); + } + } + } + + // fabric: need to change the default render material + context.pushTransform(MaterialFixer.create(material)); + + if (state.getBlock() instanceof IFunctionalCopycatBlock copycatBlock) { + FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { + BlockEntity be = blockView.getBlockEntity(pos); + if (be instanceof CTCopycatBlockEntity ctbe) + if (!ctbe.isCTEnabled()) + return false; + return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); + }); + emitBlockQuadsInner(filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } else { + emitBlockQuadsInner(blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); + } + + // fabric: pop the material changer transform + context.popTransform(); + } + + protected abstract void emitBlockQuadsInner(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData); + + @Override + public TextureAtlasSprite getParticleIcon(Object data) { + if (data instanceof BlockState state) { + BlockState material = getMaterial(state); + + return getIcon(getModelOf(material), null); + } + + return CustomParticleIconModel.super.getParticleIcon(data); + } + + public static TextureAtlasSprite getIcon(BakedModel model, @Nullable Object data) { + if (model instanceof CustomParticleIconModel particleIconModel) + return particleIconModel.getParticleIcon(data); + return model.getParticleIcon(); + } + + @Nullable + public static BlockState getMaterial(BlockState material) { + return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material; + } + + public static BakedModel getModelOf(BlockState state) { + return Minecraft.getInstance() + .getBlockRenderer() + .getBlockModel(state); + } + + public static class OcclusionData { + private final boolean[] occluded; + + public OcclusionData() { + occluded = new boolean[6]; + } + + public void occlude(Direction face) { + occluded[face.get3DDataValue()] = true; + } + + public boolean isOccluded(Direction face) { + return face == null ? false : occluded[face.get3DDataValue()]; + } + } + + public static class CullFaceRemovalData { + private final boolean[] shouldRemove; + + public CullFaceRemovalData() { + shouldRemove = new boolean[6]; + } + + public void remove(Direction face) { + shouldRemove[face.get3DDataValue()] = true; + } + + public boolean shouldRemove(Direction face) { + return face == null ? false : shouldRemove[face.get3DDataValue()]; + } + } + + public record MaterialFixer(RenderMaterial materialDefault) implements RenderContext.QuadTransform { + @Override + public boolean transform(MutableQuadView quad) { + if (quad.material().blendMode() == BlendMode.DEFAULT) { + // default needs to be changed from the Copycat's default (cutout) to the wrapped material's default. + quad.material(materialDefault); + } + return true; + } + + public static MaterialFixer create(BlockState materialState) { + RenderType type = ItemBlockRenderTypes.getChunkRenderType(materialState); + BlendMode blendMode = BlendMode.fromRenderLayer(type); + MaterialFinder finder = Objects.requireNonNull(RendererAccess.INSTANCE.getRenderer()).materialFinder(); + RenderMaterial renderMaterial = finder.blendMode(0, blendMode).find(); + return new CopycatModel.MaterialFixer(renderMaterial); + } + } +} + diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java index 603b036e7..e20c00e26 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/SimpleCopycatModel.java @@ -2,7 +2,6 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.CopycatRenderContextFabric; -import com.simibubi.create.content.decoration.copycat.CopycatModel; import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/ToggleableCopycatModelImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/ToggleableCopycatModelImpl.java index 6feb62643..e910c10c7 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/ToggleableCopycatModelImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/fabric/ToggleableCopycatModelImpl.java @@ -3,7 +3,6 @@ import com.copycatsplus.copycats.config.CCConfigs; import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.ToggleableCopycatModel; -import com.simibubi.create.content.decoration.copycat.CopycatModel; import com.tterrag.registrate.util.nullness.NonNullFunction; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.minecraft.client.resources.model.BakedModel; diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java index 3dee58c1f..4040e9880 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/MultiStateCopycatModel.java @@ -1,24 +1,18 @@ package com.copycatsplus.copycats.content.copycat.base.model.multistate.fabric; -import com.copycatsplus.copycats.Copycats; -import com.copycatsplus.copycats.content.copycat.base.multistate.MaterialItemStorage; +import com.copycatsplus.copycats.content.copycat.base.model.fabric.CopycatModel.CullFaceRemovalData; +import com.copycatsplus.copycats.content.copycat.base.model.fabric.CopycatModel.MaterialFixer; +import com.copycatsplus.copycats.content.copycat.base.model.fabric.CopycatModel.OcclusionData; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.ScaledBlockAndTintGetter; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Iterate; import io.github.fabricators_of_create.porting_lib.models.CustomParticleIconModel; -import net.fabricmc.fabric.api.renderer.v1.RendererAccess; -import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; -import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; -import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; @@ -34,7 +28,6 @@ import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.function.Supplier; public abstract class MultiStateCopycatModel extends ForwardingBakedModel implements CustomParticleIconModel { @@ -155,58 +148,4 @@ public static BakedModel getModelOf(BlockState state) { .getBlockRenderer() .getBlockModel(state); } - - - //Copied from com.simibubi.create.content.decoration.copycat.CopycatModel.OcclusionData as it was private - static class OcclusionData { - private final boolean[] occluded; - - public OcclusionData() { - occluded = new boolean[6]; - } - - public void occlude(Direction face) { - occluded[face.get3DDataValue()] = true; - } - - public boolean isOccluded(Direction face) { - return face == null ? false : occluded[face.get3DDataValue()]; - } - } - - //Copied from fabric version of create as they were private classes - protected static class CullFaceRemovalData { - private final boolean[] shouldRemove; - - public CullFaceRemovalData() { - shouldRemove = new boolean[6]; - } - - public void remove(Direction face) { - shouldRemove[face.get3DDataValue()] = true; - } - - public boolean shouldRemove(Direction face) { - return face == null ? false : shouldRemove[face.get3DDataValue()]; - } - } - - private record MaterialFixer(RenderMaterial materialDefault) implements RenderContext.QuadTransform { - @Override - public boolean transform(MutableQuadView quad) { - if (quad.material().blendMode() == BlendMode.DEFAULT) { - // default needs to be changed from the Copycat's default (cutout) to the wrapped material's default. - quad.material(materialDefault); - } - return true; - } - - public static MaterialFixer create(BlockState materialState) { - RenderType type = ItemBlockRenderTypes.getChunkRenderType(materialState); - BlendMode blendMode = BlendMode.fromRenderLayer(type); - MaterialFinder finder = Objects.requireNonNull(RendererAccess.INSTANCE.getRenderer()).materialFinder(); - RenderMaterial renderMaterial = finder.blendMode(0, blendMode).find(); - return new MaterialFixer(renderMaterial); - } - } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java deleted file mode 100644 index 08d9aa9c7..000000000 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/CopycatModelMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.copycatsplus.copycats.fabric.mixin.copycat.base; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; - -import java.util.function.Supplier; - -@Mixin(CopycatModel.class) -public class CopycatModelMixin { - @WrapOperation( - method = "emitBlockQuads", - at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/decoration/copycat/CopycatModel;emitBlockQuadsInner(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Ljava/util/function/Supplier;Lnet/fabricmc/fabric/api/renderer/v1/render/RenderContext;Lnet/minecraft/world/level/block/state/BlockState;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$CullFaceRemovalData;Lcom/simibubi/create/content/decoration/copycat/CopycatModel$OcclusionData;)V") - ) - private void fixCT(CopycatModel instance, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context, BlockState material, @Coerce Object cullFaceRemovalData, @Coerce Object occlusionData, Operation original) { - if (state.getBlock() instanceof CopycatBlock copycatBlock) { - FilteredBlockAndTintGetter filteredBlockAndTintGetter = new FilteredBlockAndTintGetter(blockView, t -> { - BlockEntity be = blockView.getBlockEntity(pos); - if (be instanceof CTCopycatBlockEntity ctbe) - if (!ctbe.isCTEnabled()) - return false; - return copycatBlock.canConnectTexturesToward(blockView, pos, t, state); - }); - original.call(instance, filteredBlockAndTintGetter, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } else { - original.call(instance, blockView, state, pos, randomSupplier, context, material, cullFaceRemovalData, occlusionData); - } - } -} diff --git a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java index 6e1ef8ee5..22a3e37f7 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/fabric/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java @@ -3,10 +3,12 @@ import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.decoration.copycat.CopycatModel; import io.github.fabricators_of_create.porting_lib.block.*; import io.github.fabricators_of_create.porting_lib.enchant.EnchantmentBonusBlock; import net.fabricmc.fabric.api.block.BlockPickInteractionAware; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -14,15 +16,13 @@ import net.minecraft.world.entity.SpawnPlacements; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.*; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.HitResult; import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Debug; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -143,4 +143,14 @@ private static R maybeMaterialAs(BlockGetter level, BlockPos pos, Class MATERIAL_PROPERTY = com.simibubi.create.content.decoration.copycat.CopycatModel.MATERIAL_PROPERTY; + private static final ModelProperty OCCLUSION_PROPERTY = new ModelProperty<>(); + private static final ModelProperty WRAPPED_DATA_PROPERTY = new ModelProperty<>(); + + public CopycatModel(BakedModel originalModel) { + super(originalModel); + } + + @Override + protected ModelData.Builder gatherModelData(ModelData.Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state, + ModelData blockEntityData) { + BlockState material = getMaterial(blockEntityData); + + builder.with(MATERIAL_PROPERTY, material); + + if (!(state.getBlock() instanceof IFunctionalCopycatBlock copycatBlock)) + return builder; + + CopycatModel.OcclusionData occlusionData = new CopycatModel.OcclusionData(); + gatherOcclusionData(world, pos, state, material, occlusionData, copycatBlock); + builder.with(OCCLUSION_PROPERTY, occlusionData); + + ModelData wrappedData = getModelOf(material).getModelData( + new FilteredBlockAndTintGetter(world, + targetPos -> { + BlockEntity be = world.getBlockEntity(pos); + if (be instanceof CTCopycatBlockEntity ctbe) + if (!ctbe.isCTEnabled()) + return false; + return copycatBlock.canConnectTexturesToward(world, pos, targetPos, state); + }), + pos, material, ModelData.EMPTY); + return builder.with(WRAPPED_DATA_PROPERTY, wrappedData); + } + + private void gatherOcclusionData(BlockAndTintGetter world, BlockPos pos, BlockState state, BlockState material, + CopycatModel.OcclusionData occlusionData, IFunctionalCopycatBlock copycatBlock) { + BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + for (Direction face : Iterate.directions) { + + // Rubidium: Run an additional IForgeBlock.hidesNeighborFace check because it + // seems to be missing in Block.shouldRenderFace + BlockPos.MutableBlockPos neighbourPos = mutablePos.setWithOffset(pos, face); + BlockState neighbourState = world.getBlockState(neighbourPos); + if (state.supportsExternalFaceHiding() + && neighbourState.hidesNeighborFace(world, neighbourPos, state, face.getOpposite())) { + occlusionData.occlude(face); + continue; + } + + if (!copycatBlock.canFaceBeOccluded(state, face)) + continue; + if (!Block.shouldRenderFace(material, world, pos, face, neighbourPos)) + occlusionData.occlude(face); + } + } + + @Override + public @NotNull List getQuads(BlockState state, Direction side, @NotNull RandomSource rand, @NotNull ModelData data, RenderType renderType) { + + // Rubidium: see below + if (side != null && state.getBlock() instanceof IFunctionalCopycatBlock ccb && ccb.shouldFaceAlwaysRender(state, side)) + return Collections.emptyList(); + + BlockState material = getMaterial(data); + + CopycatModel.OcclusionData occlusionData = data.get(OCCLUSION_PROPERTY); + if (occlusionData != null && occlusionData.isOccluded(side)) + return super.getQuads(state, side, rand, data, renderType); + + ModelData wrappedData = data.get(WRAPPED_DATA_PROPERTY); + if (wrappedData == null) + wrappedData = ModelData.EMPTY; + if (renderType != null && !Minecraft.getInstance() + .getBlockRenderer() + .getBlockModel(material) + .getRenderTypes(material, rand, wrappedData) + .contains(renderType)) + return super.getQuads(state, side, rand, data, renderType); + + List croppedQuads = getCroppedQuads(state, side, rand, material, wrappedData, renderType); + + // Rubidium: render side!=null versions of the base material during side==null, + // to avoid getting culled away + if (side == null && state.getBlock() instanceof IFunctionalCopycatBlock ccb) { + boolean immutable = true; + for (Direction nonOcclusionSide : Iterate.directions) + if (ccb.shouldFaceAlwaysRender(state, nonOcclusionSide)) { + if (immutable) { + croppedQuads = new ArrayList<>(croppedQuads); + immutable = false; + } + croppedQuads.addAll(getCroppedQuads(state, nonOcclusionSide, rand, material, wrappedData, renderType)); + } + } + + return croppedQuads; + } + + /** + * The returned list must not be mutated. + */ + public abstract List getCroppedQuads(BlockState state, Direction side, RandomSource rand, + BlockState material, ModelData wrappedData, RenderType renderType); + + @Override + public @NotNull TextureAtlasSprite getParticleIcon(@NotNull ModelData data) { + BlockState material = getMaterial(data); + + ModelData wrappedData = data.get(WRAPPED_DATA_PROPERTY); + if (wrappedData == null) + wrappedData = ModelData.EMPTY; + + return getModelOf(material).getParticleIcon(wrappedData); + } + + public static BlockState getMaterial(ModelData data) { + BlockState material = data == null ? null : data.get(MATERIAL_PROPERTY); + return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material; + } + + public static BakedModel getModelOf(BlockState state) { + return Minecraft.getInstance() + .getBlockRenderer() + .getBlockModel(state); + } + + public static class OcclusionData { + private final boolean[] occluded; + + public OcclusionData() { + occluded = new boolean[6]; + } + + public void occlude(Direction face) { + occluded[face.get3DDataValue()] = true; + } + + public boolean isOccluded(Direction face) { + return face != null && occluded[face.get3DDataValue()]; + } + } + +} diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/SimpleCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/SimpleCopycatModel.java index 939184394..140053184 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/SimpleCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/SimpleCopycatModel.java @@ -2,7 +2,6 @@ import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.assembly.forge.AssemblerImpl.CopycatRenderContextForge; -import com.simibubi.create.content.decoration.copycat.CopycatModel; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.resources.model.BakedModel; @@ -24,7 +23,7 @@ public SimpleCopycatModel(BakedModel originalModel, SimpleCopycatPart part) { } @Override - protected List getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material, ModelData wrappedData, RenderType renderType) { + public List getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material, ModelData wrappedData, RenderType renderType) { BakedModel model = getModelOf(material); List templateQuads = model.getQuads(material, side, rand, wrappedData, renderType); List quads = new ArrayList<>(); diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/ToggleableCopycatModelImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/ToggleableCopycatModelImpl.java index c8f60fd5d..a738f28fe 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/ToggleableCopycatModelImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/forge/ToggleableCopycatModelImpl.java @@ -3,8 +3,6 @@ import com.copycatsplus.copycats.config.CCConfigs; import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; import com.copycatsplus.copycats.content.copycat.base.model.ToggleableCopycatModel; -import com.copycatsplus.copycats.forge.mixin.copycat.base.CopycatModelAccessor; -import com.simibubi.create.content.decoration.copycat.CopycatModel; import com.tterrag.registrate.util.nullness.NonNullFunction; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; @@ -33,7 +31,7 @@ public ToggleableCopycatModelImpl(BakedModel originalModel, BakedModel base, Bak } @Override - protected List getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material, ModelData wrappedData, RenderType renderType) { - return ((CopycatModelAccessor) (CCConfigs.client().useEnhancedModels.get() ? enhanced : base)).callGetCroppedQuads(state, side, rand, material, wrappedData, renderType); + public List getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material, ModelData wrappedData, RenderType renderType) { + return ((CopycatModel) (CCConfigs.client().useEnhancedModels.get() ? enhanced : base)).getCroppedQuads(state, side, rand, material, wrappedData, renderType); } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java index 2e3ab6966..d1f5f447d 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -12,13 +12,14 @@ public class FunctionalCopycatRenderHelperImpl { public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { - ModelData renderData = model.getModelData(be.getLevel(), be.getBlockPos(), be.getBlockState(), be.getCopycatBlockEntity().getModelData()); + WrappedRenderWorld renderWorld = new WrappedRenderWorld(be); + ModelData renderData = model.getModelData(renderWorld, be.getBlockPos(), be.getBlockState(), be.getCopycatBlockEntity().getModelData()); ModelData.Builder builder = ModelData.builder(); copyModelData(renderData, builder); builder.with(ModelUtil.VIRTUAL_PROPERTY, true); return new BakedModelWithDataBuilder(model) - .withRenderWorld(new WrappedRenderWorld(be)) + .withRenderWorld(renderWorld) .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java index 4df1f3938..e8f121a7a 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/forge/MultiStateCopycatModel.java @@ -1,5 +1,6 @@ package com.copycatsplus.copycats.content.copycat.base.model.multistate.forge; +import com.copycatsplus.copycats.content.copycat.base.model.forge.CopycatModel.OcclusionData; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateCopycatBlockEntity; import com.copycatsplus.copycats.content.copycat.base.multistate.MultiStateTextureAtlasSprite; @@ -188,22 +189,4 @@ public static BakedModel getModelOf(BlockState state) { .getBlockRenderer() .getBlockModel(state); } - - - //Copied from com.simibubi.create.content.decoration.copycat.CopycatModel.OcclusionData as it was private - private static class OcclusionData { - private final boolean[] occluded; - - public OcclusionData() { - occluded = new boolean[6]; - } - - public void occlude(Direction face) { - occluded[face.get3DDataValue()] = true; - } - - public boolean isOccluded(Direction face) { - return face == null ? false : occluded[face.get3DDataValue()]; - } - } } diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java index 0bf7fbb6a..0a2d871e6 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftBlockEntityForge.java @@ -1,22 +1,10 @@ package com.copycatsplus.copycats.content.copycat.shaft.forge; -import com.copycatsplus.copycats.content.copycat.base.model.functional.forge.BakedModelWithDataBuilder; import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlockEntity; -import com.jozufozu.flywheel.core.model.ModelUtil; -import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; -import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.CreateClient; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; -import com.simibubi.create.foundation.render.SuperByteBuffer; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.block.BlockRenderDispatcher; -import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.client.model.data.ModelData; -import net.minecraftforge.client.model.data.ModelProperty; import org.jetbrains.annotations.NotNull; diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelAccessor.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelAccessor.java deleted file mode 100644 index 964b484a2..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelAccessor.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.copycatsplus.copycats.forge.mixin.copycat.base; - -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.core.Direction; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.client.model.data.ModelData; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.util.List; - -@Mixin(value = CopycatModel.class, remap = false) -public interface CopycatModelAccessor { - @Invoker - List callGetCroppedQuads(BlockState state, Direction side, RandomSource rand, - BlockState material, ModelData wrappedData, RenderType renderType); -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelMixin.java deleted file mode 100644 index 5225b89f6..000000000 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/CopycatModelMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.copycatsplus.copycats.forge.mixin.copycat.base; - -import com.copycatsplus.copycats.content.copycat.base.CTCopycatBlockEntity; -import com.simibubi.create.content.decoration.copycat.CopycatBlock; -import com.simibubi.create.content.decoration.copycat.CopycatModel; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = CopycatModel.class, remap = false) -public class CopycatModelMixin { - @Inject( - at = @At("HEAD"), - method = "lambda$gatherModelData$0(Lcom/simibubi/create/content/decoration/copycat/CopycatBlock;Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)Z", - cancellable = true - ) - private static void considerCT(CopycatBlock copycatBlock, BlockAndTintGetter world, BlockPos pos, BlockState state, BlockPos targetPos, CallbackInfoReturnable cir) { - BlockEntity be = world.getBlockEntity(pos); - if (!(be instanceof CTCopycatBlockEntity ctbe)) return; - if (!ctbe.isCTEnabled()) cir.setReturnValue(false); - } -} diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java index 1a1b0101d..052b86575 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/functional/FunctionalCopycatBlockMixin.java @@ -4,6 +4,7 @@ import com.copycatsplus.copycats.content.copycat.shaft.CopycatShaftBlock; import com.simibubi.create.AllBlocks; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -11,15 +12,13 @@ import net.minecraft.world.entity.SpawnPlacements; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.*; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.HitResult; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import static com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock.getMaterial; @@ -86,6 +85,14 @@ public boolean canEntityDestroy(BlockState state, BlockGetter level, BlockPos po return getMaterial(level, pos).canEntityDestroy(level, pos, entity); } + @Override + public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, @Nullable BlockState queryState, @Nullable BlockPos queryPos) { + if (isIgnoredConnectivitySide(level, state, side, pos, queryPos)) + return state; + + return getMaterial(level, pos); + } + @Override public boolean isValidSpawn(BlockState state, BlockGetter level, BlockPos pos, SpawnPlacements.Type type, EntityType entityType) { diff --git a/forge/src/main/resources/copycats-forge.mixins.json b/forge/src/main/resources/copycats-forge.mixins.json index 63ba03360..2a312ef53 100644 --- a/forge/src/main/resources/copycats-forge.mixins.json +++ b/forge/src/main/resources/copycats-forge.mixins.json @@ -7,13 +7,11 @@ "mixins": [ "compat.doubleslabs.DSConfigCommonMixin", "compat.registrate.CreateRegistrateMixin", - "copycat.base.CopycatModelMixin", "copycat.base.functional.FunctionalCopycatBlockMixin", "copycat.base.multistate.MultiStateCopycatBlockCombinerMixin", "network.ServerGamePacketListenerImplMixin" ], "client": [ - "copycat.base.CopycatModelAccessor", "featuretoggle.SubMenuConfigScreenMixin", "network.ClientPacketListenerMixin" ], From 0d3db27181ff051e89ad35c87a7ab7c833b9a173 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 11:59:17 +0800 Subject: [PATCH 61/71] Make copycat shafts cheaper to craft --- .../copycats/datagen/recipes/CCStandardRecipes.java | 2 +- .../data/copycats/recipes/stonecutting/copycat_shaft.json | 2 +- .../resources/data/create/tags/blocks/copycat_deny.json | 6 ------ .../data/copycats/recipes/stonecutting/copycat_shaft.json | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json diff --git a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java index 0543dc140..a086ed92a 100644 --- a/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java +++ b/common/src/main/java/com/copycatsplus/copycats/datagen/recipes/CCStandardRecipes.java @@ -174,7 +174,7 @@ public class CCStandardRecipes extends CopycatsRecipeProvider { GeneratedRecipe COPYCAT_SLOPE = copycat(CCBlocks.COPYCAT_SLOPE, 2); - GeneratedRecipe COPYCAT_SHAFT = copycat(CCBlocks.COPYCAT_SHAFT, 2); + GeneratedRecipe COPYCAT_SHAFT = copycat(CCBlocks.COPYCAT_SHAFT, 4); String currentFolder = ""; diff --git a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json index 42c3d3ab6..c4c1bbed2 100644 --- a/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json +++ b/fabric/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json @@ -1,6 +1,6 @@ { "type": "minecraft:stonecutting", - "count": 2, + "count": 4, "ingredient": { "tag": "c:zinc_ingots" }, diff --git a/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json b/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json deleted file mode 100644 index 91b3d67f8..000000000 --- a/fabric/src/generated/resources/data/create/tags/blocks/copycat_deny.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "create:metal_bracket" - ] -} \ No newline at end of file diff --git a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json index 4cdbc49d1..56bf6826e 100644 --- a/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json +++ b/forge/src/generated/resources/data/copycats/recipes/stonecutting/copycat_shaft.json @@ -1,6 +1,6 @@ { "type": "minecraft:stonecutting", - "count": 2, + "count": 4, "ingredient": { "tag": "forge:ingots/zinc" }, From 2dda81624702db8eda7d9e29607be592600d57fe Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 11:59:25 +0800 Subject: [PATCH 62/71] Fix placement helper --- .../copycat/shaft/CopycatShaftBlock.java | 44 +++++++++++++++++++ .../fabric/SimpleMultiStateCopycatModel.java | 19 +------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java index 35ad283b4..089c56da7 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/CopycatShaftBlock.java @@ -1,13 +1,21 @@ package com.copycatsplus.copycats.content.copycat.shaft; import com.copycatsplus.copycats.CCBlockEntityTypes; +import com.copycatsplus.copycats.CCBlocks; import com.copycatsplus.copycats.content.copycat.base.ICustomCTBlocking; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; +import com.google.common.base.Predicates; +import com.simibubi.create.AllBlocks; import com.simibubi.create.content.decoration.bracket.BracketBlock; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; +import com.simibubi.create.content.kinetics.simpleRelays.AbstractSimpleShaftBlock; import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; +import com.simibubi.create.content.kinetics.steamEngine.PoweredShaftBlock; import com.simibubi.create.foundation.placement.IPlacementHelper; import com.simibubi.create.foundation.placement.PlacementHelpers; +import com.simibubi.create.foundation.placement.PlacementOffset; +import com.simibubi.create.foundation.placement.PoleHelper; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; @@ -26,9 +34,12 @@ import org.jetbrains.annotations.Nullable; import java.util.Optional; +import java.util.function.Predicate; public class CopycatShaftBlock extends ShaftBlock implements IFunctionalCopycatBlock, ICustomCTBlocking { + public static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); + public CopycatShaftBlock(Properties properties) { super(properties); } @@ -125,4 +136,37 @@ public Optional blockCTTowards(BlockAndTintGetter reader, BlockState st public Optional isCTBlocked(BlockAndTintGetter reader, BlockState state, BlockPos pos, BlockPos connectingPos, BlockPos blockingPos, Direction face) { return Optional.of(false); } + + @MethodsReturnNonnullByDefault + private static class PlacementHelper extends PoleHelper { + // used for extending a shaft in its axis, like the piston poles. works with + // shafts and cogs + + private PlacementHelper() { + super(state -> state.getBlock() instanceof AbstractSimpleShaftBlock + || state.getBlock() instanceof PoweredShaftBlock, state -> state.getValue(AXIS), AXIS); + } + + @Override + public Predicate getItemPredicate() { + return i -> i.getItem() instanceof BlockItem + && ((BlockItem) i.getItem()).getBlock() instanceof AbstractSimpleShaftBlock; + } + + @Override + public Predicate getStatePredicate() { + return Predicates.or(AllBlocks.SHAFT::has, AllBlocks.POWERED_SHAFT::has, CCBlocks.COPYCAT_SHAFT::has); + } + + @Override + public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos, + BlockHitResult ray) { + PlacementOffset offset = super.getOffset(player, world, state, pos, ray); + if (offset.isSuccessful()) + offset.withTransform(offset.getTransform() + .andThen(s -> ShaftBlock.pickCorrectShaftType(s, world, offset.getBlockPos()))); + return offset; + } + + } } diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/SimpleMultiStateCopycatModel.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/SimpleMultiStateCopycatModel.java index 8eaa31c89..a0bc99c42 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/SimpleMultiStateCopycatModel.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/multistate/fabric/SimpleMultiStateCopycatModel.java @@ -1,12 +1,10 @@ package com.copycatsplus.copycats.content.copycat.base.model.multistate.fabric; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.Assembler; -import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl; import com.copycatsplus.copycats.content.copycat.base.model.assembly.fabric.AssemblerImpl.CopycatRenderContextFabric; +import com.copycatsplus.copycats.content.copycat.base.model.fabric.CopycatModel; import com.copycatsplus.copycats.content.copycat.base.model.multistate.SimpleMultiStateCopycatPart; import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.minecraft.client.resources.model.BakedModel; @@ -29,7 +27,7 @@ public SimpleMultiStateCopycatModel(BakedModel originalModel, SimpleMultiStateCo } @Override - protected void emitBlockQuadsInner(String key, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CullFaceRemovalData cullFaceRemovalData, OcclusionData occlusionData) { + protected void emitBlockQuadsInner(String key, BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, BlockState material, CopycatModel.CullFaceRemovalData cullFaceRemovalData, CopycatModel.OcclusionData occlusionData) { BakedModel model = getModelOf(material); // Use a mesh to defer quad emission since quads cannot be emitted inside a transform @@ -54,17 +52,4 @@ protected void emitBlockQuadsInner(String key, BlockAndTintGetter blockView, Blo meshBuilder.build().outputTo(renderContext.getEmitter()); } - - - -/* @Override - protected List getCroppedQuads(String key, BlockState state, Direction side, RandomSource rand, BlockState material, ModelData wrappedData, RenderType renderType) { - List quads = new ArrayList<>(); - List templateQuads = getModelOf(material).getQuads(material, side, rand, wrappedData, renderType); - QuadHelper.CopycatRenderContext, List> context = new QuadHelper.CopycatRenderContext<>(templateQuads, quads); - - part.emitCopycatQuads(key, state, context, material); - - return quads; - }*/ } From 6a5f7d253f9925a82f5b2738c5ec796ecad33f90 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 12:26:01 +0800 Subject: [PATCH 63/71] Fix shaft AO on fabric --- .../base/model/functional/WrappedRenderWorld.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java index 4b4362d90..f2fdee940 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; +import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import net.minecraft.client.Minecraft; @@ -26,13 +27,17 @@ public class WrappedRenderWorld implements VirtualEmptyBlockGetter { protected final BlockAndTintGetter level; + protected final IFunctionalCopycatBlock block; protected final BlockPos targetPos; protected final LevelLightEngine lightEngine; + protected final BlockState state; protected final BlockState material; public WrappedRenderWorld(IFunctionalCopycatBlockEntity be) { this.level = be.getLevel(); + this.block = (IFunctionalCopycatBlock) be.getBlockState().getBlock(); this.targetPos = be.getBlockPos(); + this.state = be.getBlockState(); this.material = be.getMaterial(); lightEngine = new LevelLightEngine(new LightChunkGetter() { @Override @@ -105,7 +110,11 @@ public BlockEntity getBlockEntity(@NotNull BlockPos pos) { @Override public @NotNull BlockState getBlockState(@NotNull BlockPos pos) { - if (!pos.equals(targetPos)) return material; + if (!pos.equals(targetPos)) { + if (block.canConnectTexturesToward(level, targetPos, pos, state)) + return material; + return Blocks.AIR.defaultBlockState(); + } return level.getBlockState(pos); } From 67ba06e4b566ff78048dde92f2e23fd994d4bef0 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 14:43:16 +0800 Subject: [PATCH 64/71] Fix shaft lighting again for both forge and fabric --- .../model/functional/WrappedRenderWorld.java | 33 +++++++++++++------ .../FunctionalCopycatRenderHelperImpl.java | 2 +- .../shaft/fabric/CopycatShaftModelFabric.java | 5 +++ .../FunctionalCopycatRenderHelperImpl.java | 4 +-- .../shaft/forge/CopycatShaftModelForge.java | 5 +++ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java index f2fdee940..89041577f 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/WrappedRenderWorld.java @@ -1,7 +1,6 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; -import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlock; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; import net.minecraft.client.Minecraft; @@ -27,17 +26,15 @@ public class WrappedRenderWorld implements VirtualEmptyBlockGetter { protected final BlockAndTintGetter level; - protected final IFunctionalCopycatBlock block; protected final BlockPos targetPos; protected final LevelLightEngine lightEngine; - protected final BlockState state; protected final BlockState material; + protected boolean ctMode = false; + public WrappedRenderWorld(IFunctionalCopycatBlockEntity be) { this.level = be.getLevel(); - this.block = (IFunctionalCopycatBlock) be.getBlockState().getBlock(); this.targetPos = be.getBlockPos(); - this.state = be.getBlockState(); this.material = be.getMaterial(); lightEngine = new LevelLightEngine(new LightChunkGetter() { @Override @@ -58,6 +55,11 @@ public LightChunk getChunkForLighting(int p_63023_, int p_63024_) { public @NotNull LayerLightEventListener getLayerListener(@NotNull LightLayer layer) { return layer == LightLayer.BLOCK ? blockListener : skyListener; } + + @Override + public int getRawBrightness(BlockPos blockPos, int amount) { + return 15; + } }; } @@ -101,6 +103,11 @@ public int getLightValue(@NotNull BlockPos pos) { }; } + public WrappedRenderWorld setCTMode(boolean ctMode) { + this.ctMode = ctMode; + return this; + } + @Override @Nullable public BlockEntity getBlockEntity(@NotNull BlockPos pos) { @@ -110,11 +117,7 @@ public BlockEntity getBlockEntity(@NotNull BlockPos pos) { @Override public @NotNull BlockState getBlockState(@NotNull BlockPos pos) { - if (!pos.equals(targetPos)) { - if (block.canConnectTexturesToward(level, targetPos, pos, state)) - return material; - return Blocks.AIR.defaultBlockState(); - } + if (!pos.equals(targetPos)) return ctMode ? material : Blocks.AIR.defaultBlockState(); return level.getBlockState(pos); } @@ -144,6 +147,16 @@ public float getShade(@NotNull Direction direction, boolean shaded) { return lightEngine; } + @Override + public int getBrightness(LightLayer lightType, BlockPos blockPos) { + return 15; + } + + @Override + public int getRawBrightness(BlockPos blockPos, int amount) { + return 15; + } + @Override public int getBlockTint(@NotNull BlockPos pos, @NotNull ColorResolver resolver) { Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS); diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java index d8f413591..663d5d549 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/fabric/FunctionalCopycatRenderHelperImpl.java @@ -13,7 +13,7 @@ public class FunctionalCopycatRenderHelperImpl { public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { return new BakedModelWithDataBuilder(model) - .withRenderWorld(new WrappedRenderWorldFabric(be)) + .withRenderWorld(new WrappedRenderWorldFabric(be).setCTMode(true)) .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) diff --git a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java index f70d8c8bd..003bd8ad6 100644 --- a/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java +++ b/fabric/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/fabric/CopycatShaftModelFabric.java @@ -26,6 +26,11 @@ public boolean isVanillaAdapter() { return false; } + @Override + public boolean useAmbientOcclusion() { + return false; + } + @Override public TextureAtlasSprite getParticleIcon(Object data) { return ((CustomParticleIconModel) copycat).getParticleIcon(data); diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java index d1f5f447d..059736686 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/forge/FunctionalCopycatRenderHelperImpl.java @@ -12,14 +12,14 @@ public class FunctionalCopycatRenderHelperImpl { public static ShadeSeparatedBufferedData getCopycatBuffer(BakedModel model, IFunctionalCopycatBlockEntity be, PoseStack ms) { - WrappedRenderWorld renderWorld = new WrappedRenderWorld(be); + WrappedRenderWorld renderWorld = new WrappedRenderWorld(be).setCTMode(true); ModelData renderData = model.getModelData(renderWorld, be.getBlockPos(), be.getBlockState(), be.getCopycatBlockEntity().getModelData()); ModelData.Builder builder = ModelData.builder(); copyModelData(renderData, builder); builder.with(ModelUtil.VIRTUAL_PROPERTY, true); return new BakedModelWithDataBuilder(model) - .withRenderWorld(renderWorld) + .withRenderWorld(renderWorld.setCTMode(false)) .withRenderPos(be.getBlockPos()) .withReferenceState(be.getBlockState()) .withPoseStack(ms) diff --git a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java index 9525f0374..2ffa12037 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java +++ b/forge/src/main/java/com/copycatsplus/copycats/content/copycat/shaft/forge/CopycatShaftModelForge.java @@ -25,6 +25,11 @@ public CopycatShaftModelForge(BakedModel template, BakedModel copycat) { this.copycat = copycat; } + @Override + public boolean useAmbientOcclusion() { + return false; + } + @Override public @NotNull TextureAtlasSprite getParticleIcon(@NotNull ModelData data) { return copycat.getParticleIcon(data); From bca637652dbd06448d9306082569b5ba85ba87b2 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 26 Jun 2024 15:06:57 +0800 Subject: [PATCH 65/71] Add warnings for existing graphics issues --- .../copycatsplus/copycats/config/CClient.java | 2 ++ .../IFunctionalCopycatBlockInstance.java | 8 +++++++- .../functional/KineticCopycatRenderData.java | 14 +++++++++++++ .../copycats/utility/ChatUtils.java | 20 +++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/com/copycatsplus/copycats/utility/ChatUtils.java diff --git a/common/src/main/java/com/copycatsplus/copycats/config/CClient.java b/common/src/main/java/com/copycatsplus/copycats/config/CClient.java index a24d7af78..b5efc9247 100644 --- a/common/src/main/java/com/copycatsplus/copycats/config/CClient.java +++ b/common/src/main/java/com/copycatsplus/copycats/config/CClient.java @@ -16,8 +16,10 @@ public String getName() { } public final ConfigBool useEnhancedModels = b(true, "useEnhancedModels", Comments.useEnhancedModels); + public final ConfigBool disableGraphicsWarnings = b(false, "disableGraphicsWarnings", Comments.disableGraphicsWarnings); private static class Comments { static String useEnhancedModels = "Use more complex copycat models to improve appearance with certain materials."; + static String disableGraphicsWarnings = "Disable warnings about graphics settings that may cause issues with the mod."; } } diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java index 420496fed..baae9c2fb 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/IFunctionalCopycatBlockInstance.java @@ -1,6 +1,7 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.utility.ChatUtils; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Material; import com.jozufozu.flywheel.api.MaterialManager; @@ -31,8 +32,13 @@ default Material getRotatingMaterial() { if (layer == null) layer = RenderLayer.TRANSPARENT; // workaround for flywheel crash when transparent layer is used in batching backend - if (Backend.getBackendType() == BackendType.BATCHING && type == RenderType.translucent()) + if (Backend.getBackendType() == BackendType.BATCHING && type == RenderType.translucent()) { type = RenderType.cutoutMipped(); + ChatUtils.sendWarningOnce( + "flywheel_batching_translucent", + "Translucent textures may appear slightly broken when using the Flywheel batching backend. Please switch to the instancing backend instead." + ); + } return getMaterialManager().state(layer, type) .material(AllMaterialSpecs.ROTATING); diff --git a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java index f0f4391b4..62c80c7a9 100644 --- a/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java +++ b/common/src/main/java/com/copycatsplus/copycats/content/copycat/base/model/functional/KineticCopycatRenderData.java @@ -1,10 +1,24 @@ package com.copycatsplus.copycats.content.copycat.base.model.functional; +import com.copycatsplus.copycats.config.CCConfigs; import com.copycatsplus.copycats.content.copycat.base.functional.IFunctionalCopycatBlockEntity; +import com.copycatsplus.copycats.utility.ChatUtils; +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.config.BackendType; +import net.minecraft.client.Minecraft; import net.minecraft.world.level.block.state.BlockState; public record KineticCopycatRenderData(BlockState state, BlockState material, boolean enableCT) { public static KineticCopycatRenderData of(IFunctionalCopycatBlockEntity be) { + if (!CCConfigs.client().disableGraphicsWarnings.get()) { + if (Backend.getBackendType() != BackendType.INSTANCING && + Minecraft.getInstance().getBlockColors().getColor(be.getMaterial(), null, null, 0) != -1) { + ChatUtils.sendWarningOnce( + "flywheel_block_color", + "Block colors may be incorrect due to the current Flywheel rendering backend. Please switch to the instancing backend to fix this." + ); + } + } return new KineticCopycatRenderData(be.getBlockState(), be.getMaterial(), be.isCTEnabled()); } } diff --git a/common/src/main/java/com/copycatsplus/copycats/utility/ChatUtils.java b/common/src/main/java/com/copycatsplus/copycats/utility/ChatUtils.java new file mode 100644 index 000000000..96d66934c --- /dev/null +++ b/common/src/main/java/com/copycatsplus/copycats/utility/ChatUtils.java @@ -0,0 +1,20 @@ +package com.copycatsplus.copycats.utility; + +import com.copycatsplus.copycats.config.CCConfigs; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; + +import java.util.HashSet; +import java.util.Set; + +public class ChatUtils { + public static Set messages = new HashSet<>(); + + public static void sendWarningOnce(String id, String message) { + if (Minecraft.getInstance().player == null) return; + if (CCConfigs.client().disableGraphicsWarnings.get()) return; + if (messages.contains(id)) return; + messages.add(id); + Minecraft.getInstance().player.sendSystemMessage(Component.literal("Warning: " + message)); + } +} From da97372a876020778503f02560ef8597a282d2ca Mon Sep 17 00:00:00 2001 From: realRobotix <82544307+realRobotix@users.noreply.github.com> Date: Wed, 26 Jun 2024 19:30:15 +0200 Subject: [PATCH 66/71] ci: initial setup --- .github/workflows/build.yml | 103 ++++++++++++++++++++++++++ .github/workflows/pull_request.yml | 65 ++++++++++++++++ .github/workflows/release.yml | 115 +++++++++++++++++++++++++++++ build.gradle | 48 +++++++++--- common/build.gradle | 14 ---- fabric/build.gradle | 25 +------ forge/build.gradle | 25 +------ gradle.properties | 4 +- 8 files changed, 327 insertions(+), 72 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/pull_request.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..8d4037dc6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,103 @@ +name: Nightly Build + +on: + workflow_dispatch: + push: + branches: + - "**multiloader" + +permissions: + contents: read + packages: write + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get branch name + id: get_branch + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + + - name: Get mod version + id: get_mod_version + run: echo "version=$(git describe --tags --abbrev=0 | grep -oP '(?<=v)\d+\.\d+\.\d+(?:-\w+)?(?=\+)')" >> $GITHUB_OUTPUT + + - name: Get MC version + uses: christian-draeger/read-properties@908f99d3334be3802ec7cb528395a69d19914e7b + id: read_properties + with: + path: gradle.properties + properties: minecraft_version enabled_platforms archives_base_name + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Validate Gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + with: + gradle-home-cache-includes: | + caches + loom-cache + + - name: Build jar + run: ./gradlew build + + - name: Publish to GitHub Packages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: env.GITHUB_TOKEN != '' + continue-on-error: true + run: ./gradlew publishMavenJavaPublicationToGitHubPackagesRepository + + - name: Publish to realRobotix Maven + env: + MAVEN_USER: ${{ secrets.MAVEN_USER }} + MAVEN_ACCESS_TOKEN: ${{ secrets.MAVEN_ACCESS_TOKEN }} + if: env.MAVEN_USER != '' && env.MAVEN_ACCESS_TOKEN != '' + run: ./gradlew publishMavenJavaPublicationToRealRobotixMavenRepository -PrealRobotixMavenUsername=${{ secrets.MAVEN_USER }} -PrealRobotixMavenPassword=${{ secrets.MAVEN_ACCESS_TOKEN }} + + - name: Find jars + id: find_jars + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "jars<<$EOF" >> $GITHUB_OUTPUT + find . -regextype posix-extended -regex "\.\/($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))\/build\/libs\/${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}\+mc\.${{ steps.read_properties.outputs.minecraft_version }}-($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))-build\.${{ github.run_number }}\.jar" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT + + - name: Send building message to discord + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + if: env.DISCORD_WEBHOOK != '' + uses: realRobotix/action-discord-notifier@master + with: + webhook: ${{ secrets.DISCORD_WEBHOOK }} + message-title: Building mod from branch ${{ steps.get_branch.outputs.branch }} + + - name: Send built file to discord + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + if: env.DISCORD_WEBHOOK != '' + run: | + while IFS= read -r f + do curl -F "file=@\"$f\";filename=\"$(echo ${f##*/} | sed 's/+/-/g')\"" $DISCORD_WEBHOOK + done <<< "${{ steps.find_jars.outputs.jars }}" + + - name: Archive Artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}+mc.${{ steps.read_properties.outputs.minecraft_version }}-build.${{ github.run_number }} + path: ${{ steps.find_jars.outputs.jars }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 000000000..cf84838f9 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,65 @@ +name: Pull Request + +on: + pull_request: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get branch name + id: get_branch + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + + - name: Get mod version + id: get_mod_version + run: echo "version=$(git describe --tags --abbrev=0 | grep -oP '(?<=v)\d+\.\d+\.\d+(?:-\w+)?(?=\+)')" >> $GITHUB_OUTPUT + + - name: Get MC version + uses: christian-draeger/read-properties@908f99d3334be3802ec7cb528395a69d19914e7b + id: read_properties + with: + path: gradle.properties + properties: minecraft_version enabled_platforms archives_base_name + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Validate Gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + with: + cache-read-only: true + + - name: Build jar + run: ./gradlew build + + - name: Find jars + id: find_jars + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "jars<<$EOF" >> $GITHUB_OUTPUT + find . -regextype posix-extended -regex "\.\/($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))\/build\/libs\/${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}\+mc\.${{ steps.read_properties.outputs.minecraft_version }}-($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))-build\.${{ github.run_number }}\.jar" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT + + - name: Archive Artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}+mc.${{ steps.read_properties.outputs.minecraft_version }}-build.${{ github.run_number }} + path: ${{ steps.find_jars.outputs.jars }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..6a4de6b5c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,115 @@ +name: Release + +on: + push: + tags: + - 'v**' + - '!v*-dev**' + +permissions: + contents: read + packages: write + +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get branch name + id: get_branch + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + + - name: Get mod version + id: get_mod_version + run: echo "version=$(git describe --tags --abbrev=0 | grep -oP '(?<=v)\d+\.\d+\.\d+(?:-\w+)?(?=\+)')" >> $GITHUB_OUTPUT + + - name: Get MC version + uses: christian-draeger/read-properties@908f99d3334be3802ec7cb528395a69d19914e7b + id: read_properties + with: + path: gradle.properties + properties: minecraft_version enabled_platforms archives_base_name + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Validate Gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + with: + gradle-home-cache-includes: | + caches + loom-cache + + - name: Build jar + env: + RELEASE: true + run: ./gradlew build + + - name: Publish to GitHub Packages + env: + RELEASE: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: env.GITHUB_TOKEN != '' + continue-on-error: true + run: ./gradlew publishMavenJavaPublicationToGitHubPackagesRepository + + - name: Publish to realRobotix Maven + env: + RELEASE: true + MAVEN_USER: ${{ secrets.MAVEN_USER }} + MAVEN_ACCESS_TOKEN: ${{ secrets.MAVEN_ACCESS_TOKEN }} + if: env.MAVEN_USER != '' && env.MAVEN_ACCESS_TOKEN != '' + run: ./gradlew publishMavenJavaPublicationToRealRobotixMavenRepository -PrealRobotixMavenUsername=${{ secrets.MAVEN_USER }} -PrealRobotixMavenPassword=${{ secrets.MAVEN_ACCESS_TOKEN }} + + - name: Publish to Modrinth and CurseForge + env: + RELEASE: true + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} + if: env.MODRINTH_TOKEN != '' && env.CURSEFORGE_TOKEN != '' + run: ./gradlew publishMods -PMODRINTH_TOKEN=${{ secrets.MODRINTH_TOKEN }} -PCURSEFORGE_TOKEN=${{ secrets.CURSEFORGE_TOKEN }} + + - name: Find jars + id: find_jars + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "jars<<$EOF" >> $GITHUB_OUTPUT + find . -regextype posix-extended -regex "\.\/($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))\/build\/libs\/${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}\+mc\.${{ steps.read_properties.outputs.minecraft_version }}-($(tr "," "|" <<< ${{ steps.read_properties.outputs.enabled_platforms }}))\.jar" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT + + - name: Send building message to discord + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + if: env.DISCORD_WEBHOOK != '' + uses: realRobotix/action-discord-notifier@master + with: + webhook: ${{ secrets.DISCORD_WEBHOOK }} + message-title: Building mod from branch ${{ steps.get_branch.outputs.branch }} + + - name: Send built file to discord + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + if: env.DISCORD_WEBHOOK != '' + run: | + while IFS= read -r f + do curl -F "file=@\"$f\";filename=\"$(echo ${f##*/} | sed 's/+/-/g')\"" $DISCORD_WEBHOOK + done <<< "${{ steps.find_jars.outputs.jars }}" + + - name: Archive Artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.read_properties.outputs.archives_base_name }}-${{ steps.get_mod_version.outputs.version }}+mc.${{ steps.read_properties.outputs.minecraft_version }} + path: ${{ steps.find_jars.outputs.jars }} diff --git a/build.gradle b/build.gradle index 313f5c5fb..8bc0a7fb5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,18 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" id "dev.architectury.loom" version "1.5.+" apply false - id 'org.ajoberstar.grgit' version '4.1.1' } -boolean isTestBuild = rootProject.is_test_build.toBoolean() +boolean ci = System.getenv("CI") != null ? System.getenv("CI").toBoolean() : false +boolean nightly = ci && (System.getenv("RELEASE") != null ? !System.getenv("RELEASE").toBoolean() : true) -project.ext { - // Open the Git repository in the current directory. - git = org.ajoberstar.grgit.Grgit.open(dir: file('.')) - // Get commit id of HEAD. - gitRevision = git.head().id - // Get abbreviated commit Id of HEAD - gitAbbRevision = git.head().abbreviatedId +def getGitTag = { -> + def stdout = new ByteArrayOutputStream() + exec { + commandLine "git", "describe", "--tags", "--abbrev=0" + standardOutput = stdout + } + return stdout.toString().trim().takeBetween("v", "+") } architectury { @@ -21,6 +21,7 @@ architectury { subprojects { apply plugin: "dev.architectury.loom" + apply plugin: "maven-publish" loom { silentMojangMappingsLicense() @@ -33,6 +34,30 @@ subprojects { parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip") } } + + publishing { + publications { + mavenJava(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + repositories { + maven { + name = "GitHubPackages" + url = "https://maven.pkg.github.com/copycats-plus/copycats" + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR") + password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") + } + } + maven { + name = "realRobotixMaven" + url = "https://maven.realrobotix.me/copycats" + credentials(PasswordCredentials) + } + } + } } allprojects { @@ -42,7 +67,8 @@ allprojects { archivesBaseName = rootProject.archives_base_name - version = project.name + "." + minecraft_version + "-" + mod_version + (isTestBuild ? "-TEST." + rootProject.gitAbbRevision : "") + String buildNumber = System.getenv("GITHUB_RUN_NUMBER") + version = "${getGitTag()}+mc.${minecraft_version}-${project.name}${nightly ? "-build.${buildNumber}" : ""}" group = rootProject.maven_group repositories { @@ -97,7 +123,7 @@ allprojects { } } - tasks.withType(JavaCompile) { + tasks.withType(JavaCompile).configureEach { options.encoding = "UTF-8" options.release.set(17) } diff --git a/common/build.gradle b/common/build.gradle index c7a6ba2d4..9838bed18 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -22,17 +22,3 @@ dependencies { annotationProcessor(implementation("io.github.llamalad7:mixinextras-common:${mixin_extras_version}")) } - -publishing { - publications { - mavenCommon(MavenPublication) { - artifactId = archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - } -} diff --git a/fabric/build.gradle b/fabric/build.gradle index f9ae13e38..f29ceb4dc 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -3,13 +3,6 @@ plugins { id 'me.modmuss50.mod-publish-plugin' version "0.5.1" } -def secrets = new Properties() -if (file("./../secrets.properties").exists()) { - file("./../secrets.properties").withInputStream { - stream -> secrets.load(stream) - } -} - architectury { platformSetupLoomIde() fabric() @@ -108,20 +101,6 @@ components.java { } } -publishing { - publications { - mavenFabric(MavenPublication) { - artifactId = archives_base_name + "-" + project.name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - } -} - tasks.publishMods.dependsOn(tasks.assemble) tasks.publishMods.mustRunAfter(tasks.build) @@ -133,7 +112,7 @@ publishMods { modLoaders.add("fabric") modrinth { - accessToken = secrets.MODRINTH_TOKEN + accessToken = project.findProperty("MODRINTH_TOKEN") projectId = "UT2M39wf" minecraftVersions.add(minecraft_version) @@ -146,7 +125,7 @@ publishMods { } curseforge { - accessToken = secrets.CURSEFORGE_TOKEN + accessToken = project.findProperty("CURSEFORGE_TOKEN") projectId = "968398" minecraftVersions.add(minecraft_version) } diff --git a/forge/build.gradle b/forge/build.gradle index 1d8b2a455..b78a8322a 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -3,13 +3,6 @@ plugins { id 'me.modmuss50.mod-publish-plugin' version "0.5.1" } -def secrets = new Properties() -if (file("./../secrets.properties").exists()) { - file("./../secrets.properties").withInputStream { - stream -> secrets.load(stream) - } -} - loom { forge { mixinConfig "copycats-common.mixins.json" @@ -114,20 +107,6 @@ components.java { } } -publishing { - publications { - mavenForge(MavenPublication) { - artifactId = archives_base_name + "-" + project.name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - } -} - tasks.publishMods.dependsOn(tasks.assemble) tasks.publishMods.mustRunAfter(tasks.build) @@ -139,7 +118,7 @@ publishMods { modLoaders.add("forge") modrinth { - accessToken = secrets.MODRINTH_TOKEN + accessToken = project.findProperty("MODRINTH_TOKEN") projectId = "UT2M39wf" minecraftVersions.add(minecraft_version) @@ -152,7 +131,7 @@ publishMods { } curseforge { - accessToken = secrets.CURSEFORGE_TOKEN + accessToken = project.findProperty("CURSEFORGE_TOKEN") projectId = "968398" minecraftVersions.add(minecraft_version) } diff --git a/gradle.properties b/gradle.properties index 1e8a8d7f4..1585169a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,9 @@ org.gradle.jvmargs=-Xmx3G +org.gradle.parallel=true +org.gradle.caching=true #Mod -archives_base_name=Copycats +archives_base_name=copycats mod_version=1.3.5 is_test_build=false maven_group=com.copycatsplus From 6500b29e22ee376a11982f375fc9302f3c74d8ff Mon Sep 17 00:00:00 2001 From: realRobotix <82544307+realRobotix@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:36:40 +0200 Subject: [PATCH 67/71] ci: remove unused properties --- gradle.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1585169a9..4839cfd26 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,8 +4,6 @@ org.gradle.caching=true #Mod archives_base_name=copycats -mod_version=1.3.5 -is_test_build=false maven_group=com.copycatsplus mod_authors=Lysine, Bennyboy1695, Redcat_XVIII # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. From 0ff21bd02fc0ae4f19b53865457155ba82c32341 Mon Sep 17 00:00:00 2001 From: realRobotix <82544307+realRobotix@users.noreply.github.com> Date: Thu, 27 Jun 2024 01:36:11 +0200 Subject: [PATCH 68/71] ci: make branch specifier more specific --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d4037dc6..e16072f1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,8 @@ on: workflow_dispatch: push: branches: - - "**multiloader" + - "multiloader" + - "*/multiloader" permissions: contents: read From 5782440d3f40ed66f5644839607801c5c2eb0e20 Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Thu, 27 Jun 2024 12:22:51 +0100 Subject: [PATCH 69/71] Fix explosion stack overflow for forge --- .../base/multistate/MultiStateCopycatBlockCombinerMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java index 958f6c404..c0dd70bd3 100644 --- a/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java +++ b/forge/src/main/java/com/copycatsplus/copycats/forge/mixin/copycat/base/multistate/MultiStateCopycatBlockCombinerMixin.java @@ -71,7 +71,7 @@ public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) { @Override public float getExplosionResistance(BlockState state, BlockGetter level, BlockPos pos, Explosion explosion) { if (state.getBlock() instanceof MultiStateCopycatBlock mscb) { - AtomicReference explosionResistance = new AtomicReference<>(state.getBlock().getExplosionResistance(state, level, pos, explosion)); + AtomicReference explosionResistance = new AtomicReference<>(state.getBlock().getExplosionResistance()); mscb.withBlockEntityDo(level, pos, mscbe -> { mscbe.getMaterialItemStorage().getAllMaterials().forEach(bs -> { explosionResistance.accumulateAndGet(bs.getBlock().getExplosionResistance(), Math::max); From f05b2a6141569c84bfb8a03583b823386e198fef Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Thu, 27 Jun 2024 12:56:29 +0100 Subject: [PATCH 70/71] Fixed merge --- common/src/main/java/com/copycatsplus/copycats/CCBlocks.java | 5 +++-- .../main/java/com/copycatsplus/copycats/CCCreativeTabs.java | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java index 2d9fd4263..3f4d84c25 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCBlocks.java @@ -489,7 +489,7 @@ public class CCBlocks { REGISTRATE.block("copycat_slope", CopycatSlopeBlock::new) .transform(BuilderTransformers.copycat()) .transform(FeatureToggle.register()) - .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(), new CopycatSlopeEnhancedModel()))) + .onRegister(CreateRegistrate.blockModel(() -> ToggleableCopycatModel.with(new CopycatSlopeModel(false), new CopycatSlopeModel(true)))) .item() .transform(customItemModel("copycat_base", "slope")) .register(); @@ -513,7 +513,8 @@ public class CCBlocks { .transform(customItemModel("copycat_base", "slope_layer")) .register(); - public static final BlockEntry COPYCAT_SHAFT = REGISTRATE.block("copycat_shaft", CopycatShaftBlock::new) + public static final BlockEntry COPYCAT_SHAFT = + REGISTRATE.block("copycat_shaft", CopycatShaftBlock::new) .transform(CCBuilderTransformers.functionalCopycat()) .transform(FeatureToggle.register()) .transform(BlockStressDefaults.setNoImpact()) diff --git a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java index b32495bb8..751c74253 100644 --- a/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java +++ b/common/src/main/java/com/copycatsplus/copycats/CCCreativeTabs.java @@ -25,8 +25,6 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_WOODEN_BUTTON, CCBlocks.COPYCAT_STONE_BUTTON, CCBlocks.COPYCAT_WOODEN_PRESSURE_PLATE, - CCBlocks.COPYCAT_SLOPE, - CCBlocks.COPYCAT_SHAFT CCBlocks.COPYCAT_STONE_PRESSURE_PLATE, CCBlocks.COPYCAT_LIGHT_WEIGHTED_PRESSURE_PLATE, CCBlocks.COPYCAT_HEAVY_WEIGHTED_PRESSURE_PLATE, @@ -49,7 +47,7 @@ public class CCCreativeTabs { CCBlocks.COPYCAT_VERTICAL_SLOPE, CCBlocks.COPYCAT_SLOPE_LAYER, /*Misc*/ - CCBlocks.SHAFT + CCBlocks.COPYCAT_SHAFT ); @ExpectPlatform From 4b8705ae32374b6232841061f8eeb343f45a029b Mon Sep 17 00:00:00 2001 From: Bennyboy1695 Date: Thu, 27 Jun 2024 13:00:27 +0100 Subject: [PATCH 71/71] Push version --- CHANGELOG.md | 12 ++++++++++++ update.json | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b76672b..2c2f4f580 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.3.5 - 2024-06-27 + +### Fixed + +- Fixed overflow issue with explosions on forge + +### Added + +- Added Vertical Slopes (better hitbox to come) +- Added Slope Layers (better hitbox to come) +- Added Copycat Shaft + ## 1.3.4 - 2024-06-19 ### Fixed diff --git a/update.json b/update.json index bbb797fd0..cb6c03581 100644 --- a/update.json +++ b/update.json @@ -1,8 +1,8 @@ { "homepage": "https://github.com/copycats-plus/copycats/", "promos": { - "1.20.1-recommended": "1.20.1-1.3.3", - "1.19.2-recommended": "1.19.2-1.3.3", - "1.18.2-recommended": "1.18.2-1.3.3" + "1.20.1-recommended": "1.20.1-1.3.5", + "1.19.2-recommended": "1.19.2-1.3.5", + "1.18.2-recommended": "1.18.2-1.3.5" } }