diff --git a/build.gradle b/build.gradle index 3d6d9dbf..f90eff32 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'maven-publish' id 'idea' id 'eclipse' - id 'fabric-loom' version '1.6.+' + id 'fabric-loom' version '1.7.+' } allprojects { diff --git a/gradle.properties b/gradle.properties index 94391f2b..a27f3c46 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,11 +1,10 @@ org.gradle.jvmargs=-Xmx2G org.gradle.parallel=true -fabric.loom.multiProjectOptimisation=true maven_group=com.terraformersmc.terraform-api -version=11.0.0-alpha.1 +version=12.0.0-alpha.1 -minecraft_version=1.21 -yarn_mappings=1.21+build.7 -loader_version=0.15.11 -fabric_version=0.100.4+1.21 +minecraft_version=1.21.2-pre3 +yarn_mappings=1.21.2-pre3+build.3 +loader_version=0.16.7 +fabric_version=0.105.4+1.21.2 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17655d0e..0d184210 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/api/block/TerraformGrassBlock.java b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/api/block/TerraformGrassBlock.java index 205ad467..906d1bcb 100644 --- a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/api/block/TerraformGrassBlock.java +++ b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/api/block/TerraformGrassBlock.java @@ -23,6 +23,7 @@ public class TerraformGrassBlock extends GrassBlock { private final Map spreadsTo; private final Supplier path; public static final Map GRASS_SPREADS_TO = new HashMap<>(); + private static final int MAX_LIGHT_LEVEL = 15; public TerraformGrassBlock(Block dirt, Supplier path, Block.Settings settings) { this(dirt, path, settings, ImmutableMap.of(Blocks.DIRT, Blocks.GRASS_BLOCK)); @@ -55,11 +56,13 @@ private static boolean canSurvive(BlockState state, WorldView world, BlockPos po BlockPos above = pos.up(); BlockState aboveState = world.getBlockState(above); - if (aboveState.getBlock() == Blocks.SNOW && aboveState.get(SnowBlock.LAYERS) == 1) { + if (aboveState.isOf(Blocks.SNOW) && aboveState.get(SnowBlock.LAYERS) == 1) { return true; + } else if (aboveState.getFluidState().getLevel() == 8) { + return false; } else { - int lightingAt = ChunkLightProvider.getRealisticOpacity(world, state, pos, aboveState, above, Direction.UP, aboveState.getOpacity(world, above)); - return lightingAt < world.getMaxLightLevel(); + int lightingAt = ChunkLightProvider.getRealisticOpacity(state, aboveState, Direction.UP, aboveState.getOpacity()); + return lightingAt < MAX_LIGHT_LEVEL; } } diff --git a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/mixin/MixinEatGrassGoal.java b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/mixin/MixinEatGrassGoal.java index 96ab4463..43aebc79 100644 --- a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/mixin/MixinEatGrassGoal.java +++ b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/mixin/MixinEatGrassGoal.java @@ -8,6 +8,7 @@ import net.minecraft.block.Blocks; import net.minecraft.entity.ai.goal.EatGrassGoal; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.world.GameRules; import net.minecraft.world.World; @@ -52,7 +53,7 @@ public class MixinEatGrassGoal { BlockState down = this.world.getBlockState(downPos); if (down.isIn(TerraformDirtBlockTags.GRASS_BLOCKS)) { - if (this.world.getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { + if (((ServerWorld) this.world).getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { this.world.syncWorldEvent(2001, downPos, Block.getRawIdFromState(Blocks.GRASS_BLOCK.getDefaultState())); Block replacement = TerraformDirtRegistryImpl.getByGrassBlock(down.getBlock()).map(DirtBlocks::getDirt).orElse(Blocks.DIRT); diff --git a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/registry/TillableBlockRegistryImpl.java b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/registry/TillableBlockRegistryImpl.java index 9e908070..48a2424c 100644 --- a/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/registry/TillableBlockRegistryImpl.java +++ b/terraform-dirt-api-v1/src/main/java/com/terraformersmc/terraform/dirt/impl/registry/TillableBlockRegistryImpl.java @@ -10,8 +10,8 @@ import java.util.function.Predicate; public final class TillableBlockRegistryImpl extends HoeItem { - private TillableBlockRegistryImpl(ToolMaterial material, Settings settings) { - super(material, settings); + private TillableBlockRegistryImpl(ToolMaterial material, float attackDamage, float attackSpeed, Settings settings) { + super(material, attackDamage, attackSpeed, settings); return; } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatType.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatType.java deleted file mode 100644 index 14ccd48f..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatType.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.terraformersmc.terraform.boat.api; - -import com.terraformersmc.terraform.boat.impl.TerraformBoatTypeImpl; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity; -import com.terraformersmc.terraform.boat.impl.entity.TerraformChestBoatEntity; - -import net.minecraft.item.Item; - -/** - * An interface representing a Terraform boat. - */ -public interface TerraformBoatType { - /** - * {@return whether this boat is a raft with a lower {@linkplain net.minecraft.entity.vehicle.BoatEntity#getMountedHeightOffset() mounted height offset}} - */ - boolean isRaft(); - - /** - * {@return the {@linkplain net.minecraft.entity.vehicle.BoatEntity#getPickBlockStack() pick stack} and {@linkplain Item item} dropped when the {@linkplain TerraformBoatEntity boat entity} is broken} - */ - Item getItem(); - - /** - * {@return the {@linkplain net.minecraft.entity.vehicle.BoatEntity#getPickBlockStack() pick stack} and {@linkplain Item item} dropped when the {@linkplain TerraformChestBoatEntity chest boat entity} is broken} - */ - Item getChestItem(); - - /** - * {@return the planks {@linkplain Item item} dropped when the {@linkplain TerraformBoatEntity boat entity} or {@linkplain TerraformChestBoatEntity chest boat entity} is destroyed into planks and sticks} - */ - Item getPlanks(); - - /** - * A builder for {@linkplain TerraformBoatType Terraform boat types}. - * - *

To build a Terraform boat type: - * - *

{@code
-	 *     TerraformBoatType boat = new TerraformBoatType.Builder()
-	 *         .item(ExampleModItems.MAHOGANY_BOAT)
-	 *         .build();
-	 * }
- */ - public static class Builder { - private boolean raft; - private Item item; - private Item chestItem; - private Item planks; - - public TerraformBoatType build() { - return new TerraformBoatTypeImpl(this.raft, this.item, this.chestItem, this.planks); - } - - /** - * @see TerraformBoatType#isRaft - */ - public Builder raft() { - this.raft = true; - return this; - } - - /** - * @see TerraformBoatType#getItem - */ - public Builder item(Item item) { - this.item = item; - return this; - } - - /** - * @see TerraformBoatType#getChestItem - */ - public Builder chestItem(Item chestItem) { - this.chestItem = chestItem; - return this; - } - - /** - * @see TerraformBoatType#getPlanks - */ - public Builder planks(Item planks) { - this.planks = planks; - return this; - } - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatTypeRegistry.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatTypeRegistry.java deleted file mode 100644 index 5ecfcd53..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/TerraformBoatTypeRegistry.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.terraformersmc.terraform.boat.api; - -import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.Identifier; - -/** - * @see TerraformBoatTypeRegistry#INSTANCE - */ -public class TerraformBoatTypeRegistry { - private static final Identifier REGISTRY_ID = Identifier.of("terraform", "boat"); - private static final RegistryKey> REGISTRY_KEY = RegistryKey.ofRegistry(REGISTRY_ID); - - /** - * The registry for {@linkplain TerraformBoatType Terraform boats}. - * - * - *

To register a boat type: - * - *

{@code
-	 *     Registry.register(TerraformBoatType.REGISTRY, Identifier.of("examplemod", "mahogany"), boat);
-	 * }
- * - * @see com.terraformersmc.terraform.boat.api.TerraformBoatType.Builder The builder for boat types - * @see com.terraformersmc.terraform.boat.api.client.TerraformBoatClientHelper Helpers for registering the boat on the client - */ - public static final Registry INSTANCE = FabricRegistryBuilder.createSimple(REGISTRY_KEY).buildAndRegister(); - - public static RegistryKey createKey(Identifier id) { - return RegistryKey.of(REGISTRY_KEY, id); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/client/TerraformBoatClientHelper.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/client/TerraformBoatClientHelper.java index 9ae5f7ca..e48bd6d6 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/client/TerraformBoatClientHelper.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/client/TerraformBoatClientHelper.java @@ -1,83 +1,35 @@ package com.terraformersmc.terraform.boat.api.client; +import com.terraformersmc.terraform.boat.impl.client.TerraformBoatClientHelperImpl; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; -import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry.TexturedModelDataProvider; -import net.minecraft.client.render.entity.model.BoatEntityModel; -import net.minecraft.client.render.entity.model.ChestBoatEntityModel; -import net.minecraft.client.render.entity.model.ChestRaftEntityModel; +import net.minecraft.client.render.entity.BoatEntityRenderer; import net.minecraft.client.render.entity.model.EntityModelLayer; -import net.minecraft.client.render.entity.model.RaftEntityModel; import net.minecraft.util.Identifier; -@Environment(EnvType.CLIENT) /** - * This class provides useful helpers for registering a {@linkplain com.terraformersmc.terraform.boat.api.TerraformBoatType Terraform boat} on the client. + * This class provides useful helpers for registering a {@linkplain net.minecraft.entity.vehicle.BoatEntity boat} on the client. */ +@Environment(EnvType.CLIENT) +@SuppressWarnings("unused") public final class TerraformBoatClientHelper { private TerraformBoatClientHelper() { return; } /** - * Gets the identifier of a {@linkplain EntityModelLayer model layer} for a boat of a given type. - * @param boatId the {@linkplain net.minecraft.util.Identifier identifier} of the {@linkplain com.terraformersmc.terraform.boat.api.TerraformBoatType boat} - * @param raft whether the boat is a raft - * @param chest whether the boat contains a chest - */ - private static Identifier getLayerId(Identifier boatId, boolean raft, boolean chest) { - String prefix = raft ? (chest ? "chest_raft/" : "raft/") : (chest ? "chest_boat/" : "boat/"); - return boatId.withPrefixedPath(prefix); - } - - /** - * Creates a {@linkplain EntityModelLayer model layer} for a boat of a given type. - * @param boatId the {@linkplain net.minecraft.util.Identifier identifier} of the {@linkplain com.terraformersmc.terraform.boat.api.TerraformBoatType boat} - * @param raft whether the boat is a raft - * @param chest whether the boat contains a chest - * - *
{@code
-	 *     EntityModelLayer layer = TerraformBoatClientHelper.getLayer(Identifier.of("examplemod", "mahogany"), false, false);
-	 * }
- */ - public static EntityModelLayer getLayer(Identifier boatId, boolean raft, boolean chest) { - return new EntityModelLayer(getLayerId(boatId, raft, chest), "main"); - } - - private static TexturedModelDataProvider getTexturedModelDataProvider(boolean raft, boolean chest) { - if (raft) { - return chest ? ChestRaftEntityModel::getTexturedModelData : RaftEntityModel::getTexturedModelData; - } else { - return chest ? ChestBoatEntityModel::getTexturedModelData : BoatEntityModel::getTexturedModelData; - } - } - - /** - * Registers a {@linkplain EntityModelLayer model layer} for a boat of a given type. - * @param boatId the {@linkplain net.minecraft.util.Identifier identifier} of the {@linkplain com.terraformersmc.terraform.boat.api.TerraformBoatType boat} - * @param raft whether the boat is a raft - * @param chest whether the boat contains a chest - * - *
{@code
-	 *     TerraformBoatClientHelper.registerModelLayer(Identifier.of("examplemod", "mahogany"), false, false);
-	 * }
- */ - private static void registerModelLayer(Identifier boatId, boolean raft, boolean chest) { - EntityModelLayerRegistry.registerModelLayer(getLayer(boatId, raft, chest), getTexturedModelDataProvider(raft, chest)); - } - - /** - * Registers {@linkplain EntityModelLayer model layers} for a given boat type. - * @param boatId the {@linkplain net.minecraft.util.Identifier identifier} of the {@linkplain com.terraformersmc.terraform.boat.api.TerraformBoatType boat type} - * @param raft whether the boat is a raft - * + * Registers {@linkplain EntityModelLayer model layers} and + * {@linkplain BoatEntityRenderer entity renderers} for all boats of given boat type. + * The provided identifier must match the identifier used to + * {@linkplain com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper#registerBoatItem register the boat type}. + * *
{@code
-	 *     TerraformBoatClientHelper.registerModelLayers(Identifier.of("examplemod", "mahogany"), false);
+	 *     TerraformBoatClientHelper.registerModelLayers(Identifier.of("examplemod", "mahogany"));
 	 * }
+ * + * @param id the {@linkplain net.minecraft.util.Identifier identifier} of the boat type. */ - public static void registerModelLayers(Identifier boatId, boolean raft) { - registerModelLayer(boatId, raft, false); - registerModelLayer(boatId, raft, true); + public static void registerModelLayers(Identifier id) { + TerraformBoatClientHelperImpl.registerModelLayers(id); } } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/item/TerraformBoatItemHelper.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/item/TerraformBoatItemHelper.java index 9cd8f0a2..be89dace 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/item/TerraformBoatItemHelper.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/api/item/TerraformBoatItemHelper.java @@ -1,91 +1,101 @@ package com.terraformersmc.terraform.boat.api.item; -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.impl.item.TerraformBoatDispenserBehavior; -import com.terraformersmc.terraform.boat.impl.item.TerraformBoatItem; - -import net.minecraft.block.DispenserBlock; +import com.terraformersmc.terraform.boat.impl.item.TerraformBoatItemHelperImpl; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.vehicle.AbstractBoatEntity; +import net.minecraft.item.BoatItem; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.registry.RegistryKey; import net.minecraft.util.Identifier; -/** - * This class provides utilities for the {@linkplain TerraformBoatItem item forms} of {@linkplain TerraformBoatType Terraform boats}, - * such as {@linkplain #registerBoatItem(Identifier, RegistryKey, boolean, Item.Settings) registering them and their dispenser behavior}. - */ +@SuppressWarnings("unused") public final class TerraformBoatItemHelper { private TerraformBoatItemHelper() { return; } /** - * Registers a {@linkplain TerraformBoatItem boat item} - * and its corresponding {@link #registerBoatDispenserBehavior dispenser behavior}. - * - *

To register a boat item and its dispenser behavior: - * + * Creates and registers a {@linkplain BoatItem boat item} and associated + * {@linkplain net.minecraft.entity.vehicle.BoatEntity boat entity} of the requested type + * and with the default {@linkplain Item.Settings}. This method assumes the type is a boat + * instead of a raft. + * + * This method should be called once for each boat type. + * Created items and entities will have identifiers similar to + * {@code id.withSuffixedPath("_boat")} and {@code id.withPrefixedPath("chest_raft/")}. + * *

{@code
-	 *     TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany_boat"), MAHOGANY_BOAT_KEY, false);
+	 *     BoatItem boat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), false);
+	 *     BoatItem chestBoat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), true);
 	 * }
- * - *

This method should be called twice for a given boat type for both boats and chest boats. - * - *

This method does not define item groups for the item. - * - * @see #registerBoatItem(Identifier, RegistryKey, boolean, Item.Settings) Helper that allows specifying a custom item settings - * - * @param id the {@linkplain Identifier identifier} to register the item with - * @param boatKey a {@linkplain RegistryKey registry key} for the {@linkplain TerraformBoatType Terraform boat type} that should be spawned by this item and dispenser behavior - * @param chest whether the boat contains a chest + * + * @param id The identifier of the boat family + * @param chest Whether the boat is a chest boat + * @return The created, registered boat item */ - public static Item registerBoatItem(Identifier id, RegistryKey boatKey, boolean chest) { - return registerBoatItem(id, boatKey, chest, new Item.Settings().maxCount(1)); + public static BoatItem registerBoatItem(Identifier id, boolean chest) { + return registerBoatItem(id, chest, false); } /** - * Registers a {@linkplain TerraformBoatItem boat item} and its corresponding {@link #registerBoatDispenserBehavior dispenser behavior}. - * - *

To register a boat item and its dispenser behavior: - * + * Creates and registers a {@linkplain BoatItem boat item} and associated + * {@linkplain net.minecraft.entity.vehicle.BoatEntity boat entity} of the requested type + * and with the default {@linkplain Item.Settings}. + * + * This method should be called once for each boat type. Both boat and raft may be registered + * for the same wood type, if desired. Created items and entities will have identifiers similar to + * {@code id.withSuffixedPath("_boat")} and {@code id.withPrefixedPath("chest_raft/")}. + * *

{@code
-	 *     TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany_boat"), MAHOGANY_BOAT_KEY, false, new Item.Settings().maxCount(1));
+	 *     BoatItem boat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), false, false);
+	 *     BoatItem chestBoat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), true, false);
 	 * }
- * - *

This method should be called twice for a given boat type for both boats and chest boats. - * - *

This method does not define item groups for the item. - * - * @param id the {@linkplain Identifier identifier} to register the item with - * @param boatKey a {@linkplain RegistryKey registry key} for the {@linkplain TerraformBoatType Terraform boat type} that should be spawned by this item and dispenser behavior - * @param chest whether the boat contains a chest + * + * @param id The identifier of the boat family + * @param chest Whether the boat is a chest boat + * @param raft Whether the boat is a raft + * @return The created, registered boat item */ - public static Item registerBoatItem(Identifier id, RegistryKey boatKey, boolean chest, Item.Settings settings) { - Item item = new TerraformBoatItem(boatKey, chest, settings); - Registry.register(Registries.ITEM, id, item); - - registerBoatDispenserBehavior(item, boatKey, chest); - return item; + public static BoatItem registerBoatItem(Identifier id, boolean chest, boolean raft) { + return registerBoatItem(id, new Item.Settings().maxCount(1), chest, raft); } /** - * Registers a {@linkplain net.minecraft.block.dispenser.DispenserBehavior dispenser behavior} that spawns a {@linkplain com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity boat entity} with a given {@linkplain TerraformBoatType Terraform boat type}. - * - *

To register a boat dispenser behavior: - * + * Creates and registers a {@linkplain BoatItem boat item} and associated + * {@linkplain net.minecraft.entity.vehicle.BoatEntity boat entity} of the requested type + * and with the provided {@linkplain Item.Settings}. + * + * This method should be called once for each boat type. Both boat and raft may be registered + * for the same wood type, if desired. Created items and entities will have identifiers similar to + * {@code id.withSuffixedPath("_boat")} and {@code id.withPrefixedPath("chest_raft/")}. + * *

{@code
-	 *     TerraformBoatItemHelper.registerBoatDispenserBehavior(MAHOGANY_BOAT_ITEM, MAHOGANY_BOAT_KEY, false);
+	 *     BoatItem boat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), settings, false, false);
+	 *     BoatItem chestBoat = TerraformBoatItemHelper.registerBoatItem(Identifier.of("examplemod", "mahogany"), settings, true, false);
 	 * }
- * - *

This method should be called twice for a given boat type for both boats and chest boats. - * - * @param item the item that should be assigned to this dispenser behavior - * @param boatKey a {@linkplain RegistryKey registry key} for the {@linkplain TerraformBoatType Terraform boat type} that should be spawned by this dispenser behavior - * @param chest whether the boat contains a chest + * + * @param id The identifier of the boat family + * @param settings Non-default item settings (f.e. changing stack size) + * @param chest Whether the boat is a chest boat + * @param raft Whether the boat is a raft + * @return The created, registered boat item + */ + public static BoatItem registerBoatItem(Identifier id, Item.Settings settings, boolean chest, boolean raft) { + return TerraformBoatItemHelperImpl.registerBoatItem(id, settings, chest, raft); + } + + /** + * Registers a vanilla {@link net.minecraft.block.dispenser.BoatDispenserBehavior boat dispenser behavior} + * for the provided {@linkplain ItemConvertible item} and + * {@linkplain net.minecraft.entity.vehicle.BoatEntity boat entity}. + * + * This registration is performed automatically by the {@linkplain TerraformBoatItemHelper#registerBoatItem} + * methods of this class. + * + * @param item The item for which to register the dispenser behavior + * @param boatEntity The boat entity which should be dispensed */ - public static void registerBoatDispenserBehavior(ItemConvertible item, RegistryKey boatKey, boolean chest) { - DispenserBlock.registerBehavior(item, new TerraformBoatDispenserBehavior(boatKey, chest)); + public static void registerBoatDispenserBehavior(ItemConvertible item, EntityType boatEntity) { + TerraformBoatItemHelperImpl.registerBoatDispenserBehavior(item, boatEntity); } } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatInitializer.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatInitializer.java deleted file mode 100644 index 92f7dfd2..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatInitializer.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.terraformersmc.terraform.boat.impl; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity; -import com.terraformersmc.terraform.boat.impl.entity.TerraformChestBoatEntity; - -import net.fabricmc.api.ModInitializer; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnGroup; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; - -public final class TerraformBoatInitializer implements ModInitializer { - private static final float DIMENSIONS_WIDTH = 1.375f; - private static final float DIMENSIONS_HEIGHT = 0.5625f; - - // Hack that prevents the following crash during client startup: - // Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry - private static final Registry registryInstance = TerraformBoatTypeRegistry.INSTANCE; - - private static final Identifier BOAT_ID = Identifier.of("terraform", "boat"); - public static final EntityType BOAT = EntityType.Builder.create(TerraformBoatEntity::new, SpawnGroup.MISC) - .dimensions(DIMENSIONS_WIDTH, DIMENSIONS_HEIGHT) - .build(); - - private static final Identifier CHEST_BOAT_ID = Identifier.of("terraform", "chest_boat"); - public static final EntityType CHEST_BOAT = EntityType.Builder.create(TerraformChestBoatEntity::new, SpawnGroup.MISC) - .dimensions(DIMENSIONS_WIDTH, DIMENSIONS_HEIGHT) - .build(); - - @Override - public void onInitialize() { - TerraformBoatTrackedData.register(); - Registry.register(Registries.ENTITY_TYPE, BOAT_ID, BOAT); - Registry.register(Registries.ENTITY_TYPE, CHEST_BOAT_ID, CHEST_BOAT); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTrackedData.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTrackedData.java deleted file mode 100644 index ce1f2512..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTrackedData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.terraformersmc.terraform.boat.impl; - -import java.util.Optional; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; - -import net.minecraft.entity.data.TrackedDataHandler; -import net.minecraft.entity.data.TrackedDataHandlerRegistry; -import net.minecraft.network.RegistryByteBuf; -import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; - -public final class TerraformBoatTrackedData { - private TerraformBoatTrackedData() { - return; - } - - public static final PacketCodec> PACKET_CODEC = PacketCodecs - .registryValue(TerraformBoatTypeRegistry.INSTANCE.getKey()) - .collect(PacketCodecs::optional); - - public static final TrackedDataHandler> HANDLER = TrackedDataHandler.create(PACKET_CODEC); - - protected static void register() { - TrackedDataHandlerRegistry.register(HANDLER); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTypeImpl.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTypeImpl.java deleted file mode 100644 index 92bb2562..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/TerraformBoatTypeImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.terraformersmc.terraform.boat.impl; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; - -import net.minecraft.item.Item; - -/** - * A simple implementation of {@link TerraformBoatType}. - */ -public class TerraformBoatTypeImpl implements TerraformBoatType { - private final boolean raft; - private final Item item; - private final Item chestItem; - private final Item planks; - - public TerraformBoatTypeImpl(boolean raft, Item item, Item chestItem, Item planks) { - this.raft = raft; - this.item = item; - this.chestItem = chestItem; - this.planks = planks; - } - - @Override - public boolean isRaft() { - return this.raft; - } - - @Override - public Item getItem() { - return this.item; - } - - @Override - public Item getChestItem() { - return this.chestItem; - } - - @Override - public Item getPlanks() { - return this.planks; - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientHelperImpl.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientHelperImpl.java new file mode 100644 index 00000000..5faa39da --- /dev/null +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientHelperImpl.java @@ -0,0 +1,48 @@ +package com.terraformersmc.terraform.boat.impl.client; + +import com.terraformersmc.terraform.boat.impl.data.TerraformBoatData; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry.TexturedModelDataProvider; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; +import net.minecraft.client.render.entity.BoatEntityRenderer; +import net.minecraft.client.render.entity.model.BoatEntityModel; +import net.minecraft.client.render.entity.model.EntityModelLayer; +import net.minecraft.client.render.entity.model.RaftEntityModel; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.vehicle.AbstractBoatEntity; +import net.minecraft.util.Identifier; + +@Environment(EnvType.CLIENT) +public final class TerraformBoatClientHelperImpl { + private TerraformBoatClientHelperImpl() { + return; + } + + private static void registerEntityRenderer(EntityType entityType, EntityModelLayer modelLayer, TexturedModelDataProvider texturedModelDataProvider) { + EntityModelLayerRegistry.registerModelLayer(modelLayer, texturedModelDataProvider); + EntityRendererRegistry.register(entityType, context -> new BoatEntityRenderer(context, modelLayer)); + } + + public static void registerModelLayers(Identifier id) { + TerraformBoatData boatData = TerraformBoatData.get(id); + + if (boatData.boatEntity() != null) { + registerEntityRenderer(boatData.boatEntity(), boatData.boatModelLayer(), + BoatEntityModel::getTexturedModelData); + } + if (boatData.chestBoatEntity() != null) { + registerEntityRenderer(boatData.chestBoatEntity(), boatData.chestBoatModelLayer(), + BoatEntityModel::getChestTexturedModelData); + } + if (boatData.raftEntity() != null) { + registerEntityRenderer(boatData.raftEntity(), boatData.raftModelLayer(), + RaftEntityModel::getTexturedModelData); + } + if (boatData.chestRaftEntity() != null) { + registerEntityRenderer(boatData.chestRaftEntity(), boatData.chestRaftModelLayer(), + RaftEntityModel::getChestTexturedModelData); + } + } +} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientInitializer.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientInitializer.java deleted file mode 100644 index ff9a3572..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatClientInitializer.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.client; - -import com.terraformersmc.terraform.boat.impl.TerraformBoatInitializer; - -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; - -@Environment(EnvType.CLIENT) -public final class TerraformBoatClientInitializer implements ClientModInitializer { - @Override - public void onInitializeClient() { - EntityRendererRegistry.register(TerraformBoatInitializer.BOAT, context -> new TerraformBoatEntityRenderer(context, false)); - EntityRendererRegistry.register(TerraformBoatInitializer.CHEST_BOAT, context -> new TerraformBoatEntityRenderer(context, true)); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatEntityRenderer.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatEntityRenderer.java deleted file mode 100644 index be8691b2..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/client/TerraformBoatEntityRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.client; - -import java.util.Map; - -import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.util.Pair; -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; -import com.terraformersmc.terraform.boat.api.client.TerraformBoatClientHelper; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatHolder; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.model.ModelPart; -import net.minecraft.client.render.entity.BoatEntityRenderer; -import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.entity.model.BoatEntityModel; -import net.minecraft.client.render.entity.model.ChestBoatEntityModel; -import net.minecraft.client.render.entity.model.ChestRaftEntityModel; -import net.minecraft.client.render.entity.model.CompositeEntityModel; -import net.minecraft.client.render.entity.model.EntityModelLayer; -import net.minecraft.client.render.entity.model.RaftEntityModel; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.util.Identifier; - -@Environment(EnvType.CLIENT) -public class TerraformBoatEntityRenderer extends BoatEntityRenderer { - private final Map>> texturesAndModels; - - public TerraformBoatEntityRenderer(EntityRendererFactory.Context context, boolean chest) { - super(context, chest); - - this.texturesAndModels = TerraformBoatTypeRegistry.INSTANCE.getEntrySet().stream().collect(ImmutableMap.toImmutableMap(entry -> { - return entry.getValue(); - }, entry -> { - boolean raft = entry.getValue().isRaft(); - String prefix = raft ? (chest ? "chest_raft/" : "raft/") : (chest ? "chest_boat/" : "boat/"); - - Identifier id = entry.getKey().getValue(); - Identifier textureId = id.withPath(path -> "textures/entity/" + prefix + path + ".png"); - - EntityModelLayer layer = TerraformBoatClientHelper.getLayer(id, raft, chest); - CompositeEntityModel model = createModel(context.getPart(layer), raft, chest); - - return new Pair<>(textureId, model); - })); - } - - @Override - public Identifier getTexture(BoatEntity entity) { - if (entity instanceof TerraformBoatHolder) { - TerraformBoatType boat = ((TerraformBoatHolder) entity).getTerraformBoat(); - return this.texturesAndModels.get(boat).getFirst(); - } - return super.getTexture(entity); - } - - public Pair> getTextureAndModel(TerraformBoatHolder holder) { - return this.texturesAndModels.get(holder.getTerraformBoat()); - } - - private CompositeEntityModel createModel(ModelPart part, boolean raft, boolean chest) { - if (raft) { - return chest ? new ChestRaftEntityModel(part) : new RaftEntityModel(part); - } else { - return chest ? new ChestBoatEntityModel(part) : new BoatEntityModel(part); - } - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/data/TerraformBoatData.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/data/TerraformBoatData.java new file mode 100644 index 00000000..a2695605 --- /dev/null +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/data/TerraformBoatData.java @@ -0,0 +1,120 @@ +package com.terraformersmc.terraform.boat.impl.data; + +import net.minecraft.client.render.entity.model.EntityModelLayer; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.vehicle.*; +import net.minecraft.util.Identifier; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This internal implementation class provides data records used by + * {@linkplain com.terraformersmc.terraform.boat.api.client.TerraformBoatClientHelper Terraform boat helper} + * to complete client-side registration of the entities, models, and layers. + */ +public record TerraformBoatData(Identifier id, EntityType boatEntity, EntityType chestBoatEntity, EntityType raftEntity, EntityType chestRaftEntity) { + private static final Map BOAT_DATA = new ConcurrentHashMap<>(); + + public TerraformBoatData { + Objects.requireNonNull(id); + } + + public static void put(TerraformBoatData boatData) { + BOAT_DATA.put(boatData.id, boatData); + } + + public static TerraformBoatData get(Identifier id) { + Objects.requireNonNull(id); + if (!BOAT_DATA.containsKey(id)) { + throw new RuntimeException("Request for unregistered boat data: " + id); + } + + return BOAT_DATA.get(id); + } + + public static TerraformBoatData empty(Identifier id) { + return new TerraformBoatData(id, null, null, null, null); + } + + public static void addBoat(Identifier id, EntityType boatEntity) { + if (BOAT_DATA.containsKey(id)) { + TerraformBoatData old = BOAT_DATA.get(id); + if (old.boatEntity != null) { + throw new IllegalStateException("Attempted to replace existing boat entity: " + old.boatId()); + } + put(new TerraformBoatData(id, boatEntity, old.chestBoatEntity, old.raftEntity, old.chestRaftEntity)); + } else { + put(new TerraformBoatData(id, boatEntity, null, null, null)); + } + } + + public static void addChestBoat(Identifier id, EntityType chestBoatEntity) { + if (BOAT_DATA.containsKey(id)) { + TerraformBoatData old = BOAT_DATA.get(id); + if (old.chestBoatEntity != null) { + throw new IllegalStateException("Attempted to replace existing chest boat entity: " + old.chestBoatId()); + } + put(new TerraformBoatData(id, old.boatEntity, chestBoatEntity, old.raftEntity, old.chestRaftEntity)); + } else { + put(new TerraformBoatData(id, null, chestBoatEntity, null, null)); + } + } + + public static void addRaft(Identifier id, EntityType raftEntity) { + if (BOAT_DATA.containsKey(id)) { + TerraformBoatData old = BOAT_DATA.get(id); + if (old.raftEntity != null) { + throw new IllegalStateException("Attempted to replace existing raft entity: " + old.raftId()); + } + put(new TerraformBoatData(id, old.boatEntity, old.chestBoatEntity, raftEntity, old.chestRaftEntity)); + } else { + put(new TerraformBoatData(id, null, null, raftEntity, null)); + } + } + + public static void addChestRaft(Identifier id, EntityType chestRaftEntity) { + if (BOAT_DATA.containsKey(id)) { + TerraformBoatData old = BOAT_DATA.get(id); + if (old.chestRaftEntity != null) { + throw new IllegalStateException("Attempted to replace existing chest raft entity: " + old.chestRaftId()); + } + put(new TerraformBoatData(id, old.boatEntity, old.chestBoatEntity, old.raftEntity, chestRaftEntity)); + } else { + put(new TerraformBoatData(id, null, null, null, chestRaftEntity)); + } + } + + public Identifier boatId() { + return id.withSuffixedPath("_boat"); + } + + public Identifier chestBoatId() { + return id.withSuffixedPath("_chest_boat"); + } + + public EntityModelLayer boatModelLayer() { + return new EntityModelLayer(id.withPrefixedPath("boat/"), "main"); + } + + public EntityModelLayer chestBoatModelLayer() { + return new EntityModelLayer(id.withPrefixedPath("chest_boat/"), "main"); + } + + public Identifier raftId() { + return id.withSuffixedPath("_raft"); + } + + public Identifier chestRaftId() { + return id.withSuffixedPath("_chest_raft"); + } + + public EntityModelLayer raftModelLayer() { + return new EntityModelLayer(id.withPrefixedPath("raft/"), "main"); + } + + public EntityModelLayer chestRaftModelLayer() { + return new EntityModelLayer(id.withPrefixedPath("chest_raft/"), "main"); + } +} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatEntity.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatEntity.java deleted file mode 100644 index 7a4f2ee1..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatEntity.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.entity; - -import java.util.Optional; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.impl.TerraformBoatInitializer; -import com.terraformersmc.terraform.boat.impl.TerraformBoatTrackedData; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.data.DataTracker; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.text.Text; -import net.minecraft.world.World; - -/** - * A {@linkplain BoatEntity boat entity} that stores a {@linkplain TerraformBoatType Terraform boat type}. - */ -public class TerraformBoatEntity extends BoatEntity implements TerraformBoatHolder { - private static final TrackedData> TERRAFORM_BOAT = DataTracker.registerData(TerraformBoatEntity.class, TerraformBoatTrackedData.HANDLER); - - public TerraformBoatEntity(EntityType type, World world) { - super(type, world); - } - - public TerraformBoatEntity(World world) { - this(TerraformBoatInitializer.BOAT, world); - } - - public TerraformBoatEntity(World world, double x, double y, double z) { - this(TerraformBoatInitializer.BOAT, world); - - this.setPosition(x, y, z); - this.prevX = x; - this.prevY = y; - this.prevZ = z; - } - - @Override - public TerraformBoatType getTerraformBoat() { - return this.dataTracker.get(TERRAFORM_BOAT).orElse(null); - } - - @Override - public void setTerraformBoat(TerraformBoatType boat) { - this.dataTracker.set(TERRAFORM_BOAT, Optional.of(boat)); - } - - @Override - protected Text getDefaultName() { - if (this.getTerraformBoat() == null) { - return EntityType.BOAT.getName(); - } - - return super.getDefaultName(); - } - - @Override - public Item asItem() { - return this.getTerraformBoat().getItem(); - } - - @Override - public boolean shouldRender(double cameraX, double cameraY, double cameraZ) { - return this.hasValidTerraformBoat() && super.shouldRender(cameraX, cameraY, cameraZ); - } - - @Override - public void tick() { - if (this.hasValidTerraformBoat()) { - super.tick(); - } else { - this.discard(); - } - } - - @Override - public void setVariant(BoatEntity.Type type) { - return; - } - - @Override - public BoatEntity.Type getVariant() { - return this.getImpersonatedBoatType(); - } - - @Override - protected void initDataTracker(DataTracker.Builder builder) { - super.initDataTracker(builder); - builder.add(TERRAFORM_BOAT, Optional.empty()); - } - - // Serialization - @Override - protected void readCustomDataFromNbt(NbtCompound nbt) { - super.readCustomDataFromNbt(nbt); - this.readTerraformBoatFromNbt(nbt); - - if (!this.hasValidTerraformBoat()) { - this.discard(); - } - } - - @Override - protected void writeCustomDataToNbt(NbtCompound nbt) { - super.writeCustomDataToNbt(nbt); - this.writeTerraformBoatToNbt(nbt); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatHolder.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatHolder.java deleted file mode 100644 index cf74f341..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformBoatHolder.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.entity; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; - -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.util.Identifier; - -public interface TerraformBoatHolder { - static final String BOAT_KEY = "TerraformBoat"; - - TerraformBoatType getTerraformBoat(); - - void setTerraformBoat(TerraformBoatType boat); - - default boolean hasValidTerraformBoat() { - return this.getTerraformBoat() != null; - } - - default void readTerraformBoatFromNbt(NbtCompound nbt) { - Identifier id = Identifier.tryParse(nbt.getString(BOAT_KEY)); - if (id != null) { - TerraformBoatType boat = TerraformBoatTypeRegistry.INSTANCE.get(id); - if (boat != null) { - this.setTerraformBoat(boat); - } - } - } - - default void writeTerraformBoatToNbt(NbtCompound nbt) { - Identifier boatId = TerraformBoatTypeRegistry.INSTANCE.getId(this.getTerraformBoat()); - if (boatId != null) { - nbt.putString(BOAT_KEY, boatId.toString()); - } - } - - default BoatEntity.Type getImpersonatedBoatType() { - return this.getTerraformBoat().isRaft() ? BoatEntity.Type.BAMBOO : BoatEntity.Type.OAK; - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformChestBoatEntity.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformChestBoatEntity.java deleted file mode 100644 index 39192ab5..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/entity/TerraformChestBoatEntity.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.entity; - -import java.util.Optional; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.impl.TerraformBoatInitializer; -import com.terraformersmc.terraform.boat.impl.TerraformBoatTrackedData; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.data.DataTracker; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.entity.vehicle.ChestBoatEntity; -import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.text.Text; -import net.minecraft.world.World; - -/** - * A {@linkplain ChestBoatEntity chest boat entity} that stores a {@linkplain TerraformBoatType Terraform boat type}. - */ -public class TerraformChestBoatEntity extends ChestBoatEntity implements TerraformBoatHolder { - private static final TrackedData> TERRAFORM_BOAT = DataTracker.registerData(TerraformChestBoatEntity.class, TerraformBoatTrackedData.HANDLER); - - public TerraformChestBoatEntity(EntityType type, World world) { - super(type, world); - } - - public TerraformChestBoatEntity(World world) { - this(TerraformBoatInitializer.CHEST_BOAT, world); - } - - public TerraformChestBoatEntity(World world, double x, double y, double z) { - this(TerraformBoatInitializer.CHEST_BOAT, world); - - this.setPosition(x, y, z); - this.prevX = x; - this.prevY = y; - this.prevZ = z; - } - - @Override - public TerraformBoatType getTerraformBoat() { - return this.dataTracker.get(TERRAFORM_BOAT).orElse(null); - } - - @Override - public void setTerraformBoat(TerraformBoatType boat) { - this.dataTracker.set(TERRAFORM_BOAT, Optional.of(boat)); - } - - @Override - protected Text getDefaultName() { - if (this.getTerraformBoat() == null) { - return EntityType.CHEST_BOAT.getName(); - } - - return super.getDefaultName(); - } - - @Override - public Item asItem() { - return this.getTerraformBoat().getChestItem(); - } - - @Override - public boolean shouldRender(double cameraX, double cameraY, double cameraZ) { - return this.hasValidTerraformBoat() && super.shouldRender(cameraX, cameraY, cameraZ); - } - - @Override - public void tick() { - if (this.hasValidTerraformBoat()) { - super.tick(); - } else { - this.discard(); - } - } - - @Override - public void setVariant(BoatEntity.Type type) { - return; - } - - @Override - public BoatEntity.Type getVariant() { - return this.getImpersonatedBoatType(); - } - - @Override - protected void initDataTracker(DataTracker.Builder builder) { - super.initDataTracker(builder); - builder.add(TERRAFORM_BOAT, Optional.empty()); - } - - // Serialization - @Override - protected void readCustomDataFromNbt(NbtCompound nbt) { - super.readCustomDataFromNbt(nbt); - this.readTerraformBoatFromNbt(nbt); - - if (!this.hasValidTerraformBoat()) { - this.discard(); - } - } - - @Override - protected void writeCustomDataToNbt(NbtCompound nbt) { - super.writeCustomDataToNbt(nbt); - this.writeTerraformBoatToNbt(nbt); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatDispenserBehavior.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatDispenserBehavior.java deleted file mode 100644 index fbb3ea40..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatDispenserBehavior.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.item; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity; -import com.terraformersmc.terraform.boat.impl.entity.TerraformChestBoatEntity; - -import net.minecraft.block.DispenserBlock; -import net.minecraft.block.dispenser.DispenserBehavior; -import net.minecraft.block.dispenser.ItemDispenserBehavior; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.tag.FluidTags; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPointer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; - -/** - * A {@linkplain DispenserBehavior dispenser behavior} that spawns a {@linkplain TerraformBoatEntity boat entity} with a given {@linkplain TerraformBoatType Terraform boat type}. - */ -public class TerraformBoatDispenserBehavior extends ItemDispenserBehavior { - private static final DispenserBehavior FALLBACK_BEHAVIOR = new ItemDispenserBehavior(); - private static final double OFFSET_MULTIPLIER = 1.125F; - - private final RegistryKey boatKey; - private final boolean chest; - - /** - * @param boatKey a {@linkplain RegistryKey registry key} for the {@linkplain TerraformBoatType Terraform boat type} that should be spawned by this dispenser behavior - * @param chest whether the boat contains a chest - */ - public TerraformBoatDispenserBehavior(RegistryKey boatKey, boolean chest) { - this.boatKey = boatKey; - this.chest = chest; - } - - @Override - public ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { - Direction facing = pointer.state().get(DispenserBlock.FACING); - ServerWorld world = pointer.world(); - Vec3d centerPos = pointer.centerPos(); - - double horizontalOffsetMultiplier = (OFFSET_MULTIPLIER + EntityType.BOAT.getWidth()) / 2.0d; - double x = centerPos.getX() + facing.getOffsetX() * horizontalOffsetMultiplier; - double y = centerPos.getY() + facing.getOffsetY() * OFFSET_MULTIPLIER; - double z = centerPos.getZ() + facing.getOffsetZ() * horizontalOffsetMultiplier; - - BlockPos pos = pointer.pos().offset(facing); - - if (world.getFluidState(pos).isIn(FluidTags.WATER)) { - y += 1.0d; - } else if (!world.getBlockState(pos).isAir() || !world.getFluidState(pos.down()).isIn(FluidTags.WATER)) { - return FALLBACK_BEHAVIOR.dispense(pointer, stack); - } - - TerraformBoatType boatType = TerraformBoatTypeRegistry.INSTANCE.getOrThrow(this.boatKey); - BoatEntity boatEntity; - - if (this.chest) { - TerraformChestBoatEntity chestBoat = new TerraformChestBoatEntity(world, x, y, z); - chestBoat.setTerraformBoat(boatType); - boatEntity = chestBoat; - } else { - TerraformBoatEntity boat = new TerraformBoatEntity(world, x, y, z); - boat.setTerraformBoat(boatType); - boatEntity = boat; - } - - boatEntity.setYaw(facing.asRotation()); - - world.spawnEntity(boatEntity); - - stack.decrement(1); - return stack; - } - - @Override - protected void playSound(BlockPointer pointer) { - pointer.world().syncWorldEvent(1000, pointer.pos(), 0); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItem.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItem.java deleted file mode 100644 index 1dd2f953..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItem.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.item; - -import java.util.List; -import java.util.function.Predicate; - -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity; -import com.terraformersmc.terraform.boat.impl.entity.TerraformChestBoatEntity; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.registry.RegistryKey; -import net.minecraft.stat.Stats; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.RaycastContext; -import net.minecraft.world.World; -import net.minecraft.world.event.GameEvent; - -/** - * An {@linkplain Item item} that spawns a {@linkplain TerraformBoatEntity boat entity} with a given {@linkplain TerraformBoatType Terraform boat type}. - */ -public class TerraformBoatItem extends Item { - private static final Predicate RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::canHit); - - private final RegistryKey boatKey; - private final boolean chest; - - /** - * @param boatKey a {@linkplain RegistryKey registry key} for the {@linkplain TerraformBoatType Terraform boat type} that should be spawned by this item - */ - public TerraformBoatItem(RegistryKey boatKey, boolean chest, Item.Settings settings) { - super(settings); - - this.boatKey = boatKey; - this.chest = chest; - } - - public TypedActionResult use(World world, PlayerEntity user, Hand hand) { - ItemStack stack = user.getStackInHand(hand); - - BlockHitResult hitResult = Item.raycast(world, user, RaycastContext.FluidHandling.ANY); - if (hitResult.getType() == HitResult.Type.MISS) { - return TypedActionResult.pass(stack); - } - - Vec3d rotationVec = user.getRotationVec(1f); - List riders = world.getOtherEntities(user, user.getBoundingBox().stretch(rotationVec.multiply(5d)).expand(1d), RIDERS); - - // Prevent collision with user - if (!riders.isEmpty()) { - Vec3d eyePos = user.getEyePos(); - for (Entity entity : riders) { - Box box = entity.getBoundingBox().expand(entity.getTargetingMargin()); - if (box.contains(eyePos)) { - return TypedActionResult.pass(stack); - } - } - } - - // Spawn boat entity - if (hitResult.getType() == HitResult.Type.BLOCK) { - double x = hitResult.getPos().x; - double y = hitResult.getPos().y; - double z = hitResult.getPos().z; - - TerraformBoatType boatType = TerraformBoatTypeRegistry.INSTANCE.getOrThrow(this.boatKey); - BoatEntity boatEntity; - - if (this.chest) { - TerraformChestBoatEntity chestBoat = new TerraformChestBoatEntity(world, x, y, z); - chestBoat.setTerraformBoat(boatType); - boatEntity = chestBoat; - } else { - TerraformBoatEntity boat = new TerraformBoatEntity(world, x, y, z); - boat.setTerraformBoat(boatType); - boatEntity = boat; - } - - boatEntity.setYaw(user.getYaw()); - - if (!world.isSpaceEmpty(boatEntity, boatEntity.getBoundingBox().expand(-0.1d))) { - return TypedActionResult.fail(stack); - } - - if (!world.isClient()) { - world.spawnEntity(boatEntity); - world.emitGameEvent(user, GameEvent.ENTITY_PLACE, hitResult.getPos()); - - if (!user.getAbilities().creativeMode) { - stack.decrement(1); - } - } - - user.incrementStat(Stats.USED.getOrCreateStat(this)); - return TypedActionResult.success(stack, world.isClient()); - } - - return TypedActionResult.pass(stack); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItemHelperImpl.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItemHelperImpl.java new file mode 100644 index 00000000..61a48e2b --- /dev/null +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/item/TerraformBoatItemHelperImpl.java @@ -0,0 +1,113 @@ +package com.terraformersmc.terraform.boat.impl.item; + +import com.terraformersmc.terraform.boat.impl.data.TerraformBoatData; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.BoatDispenserBehavior; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.entity.vehicle.*; +import net.minecraft.item.BoatItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; + +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +public final class TerraformBoatItemHelperImpl { + private TerraformBoatItemHelperImpl() { + return; + } + + private static EntityType.EntityFactory getBoatFactory(Supplier itemSupplier) { + return (type, world) -> new BoatEntity(type, world, itemSupplier); + } + + private static EntityType.EntityFactory getChestBoatFactory(Supplier itemSupplier) { + return (type, world) -> new ChestBoatEntity(type, world, itemSupplier); + } + + private static EntityType.EntityFactory getRaftFactory(Supplier itemSupplier) { + return (type, world) -> new RaftEntity(type, world, itemSupplier); + } + + private static EntityType.EntityFactory getChestRaftFactory(Supplier itemSupplier) { + return (type, world) -> new ChestRaftEntity(type, world, itemSupplier); + } + + private static EntityType.Builder createEntityTypeBuilder(EntityType.EntityFactory factory) { + return EntityType.Builder.create(factory, SpawnGroup.MISC) + .dropsNothing() + .dimensions(1.375f, 0.5625f) + .eyeHeight(0.5625f) + .maxTrackingRange(10); + } + + private static EntityType registerEntityType(Identifier id, EntityType.Builder type) { + RegistryKey> key = RegistryKey.of(RegistryKeys.ENTITY_TYPE, id); + + return Registry.register(Registries.ENTITY_TYPE, key, type.build(key)); + } + + private static BoatItem registerBoat(Identifier id, Identifier boatId, Item.Settings settings, Function, EntityType.EntityFactory> factory, BiConsumer> registry) { + DelayedItemSupplier itemSupplier = new DelayedItemSupplier(); + EntityType entityType = registerEntityType(boatId, createEntityTypeBuilder(factory.apply(itemSupplier))); + + RegistryKey itemKey = RegistryKey.of(RegistryKeys.ITEM, boatId); + BoatItem item = Registry.register(Registries.ITEM, itemKey, new BoatItem(entityType, settings.registryKey(itemKey))); + + itemSupplier.set(item); + registry.accept(id, entityType); + registerBoatDispenserBehavior(item, entityType); + + return item; + } + + + public static BoatItem registerBoatItem(Identifier id, Item.Settings settings, boolean chest, boolean raft) { + TerraformBoatData boatData = TerraformBoatData.empty(id); + + if (raft) { + if (chest) { + return registerBoat(id, boatData.chestRaftId(), settings, + TerraformBoatItemHelperImpl::getChestRaftFactory, TerraformBoatData::addChestRaft); + } else { + return registerBoat(id, boatData.raftId(), settings, + TerraformBoatItemHelperImpl::getRaftFactory, TerraformBoatData::addRaft); + } + } else { + if (chest) { + return registerBoat(id, boatData.chestBoatId(), settings, + TerraformBoatItemHelperImpl::getChestBoatFactory, TerraformBoatData::addChestBoat); + } else { + return registerBoat(id, boatData.boatId(), settings, + TerraformBoatItemHelperImpl::getBoatFactory, TerraformBoatData::addBoat); + } + } + } + + public static void registerBoatDispenserBehavior(ItemConvertible item, EntityType boatEntity) { + DispenserBlock.registerBehavior(item, new BoatDispenserBehavior(boatEntity)); + } + + + private static class DelayedItemSupplier implements Supplier { + Item value = Items.AIR; + + public void set(Item value) { + this.value = value; + } + + @Override + public Item get() { + return this.value; + } + } +} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntity.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntity.java deleted file mode 100644 index 0e5b2107..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntity.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatHolder; - -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.item.ItemConvertible; - -@Mixin(BoatEntity.class) -public class MixinBoatEntity { - @ModifyArg(method = "fall(DZLnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V", index = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/vehicle/BoatEntity;dropItem(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/entity/ItemEntity;", ordinal = 0)) - private ItemConvertible terraformWood$replacePlanksDropItem(ItemConvertible original) { - if (this instanceof TerraformBoatHolder terraformBoatHolder) { - return terraformBoatHolder.getTerraformBoat().getPlanks(); - } - - return original; - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntityRenderer.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntityRenderer.java deleted file mode 100644 index 1c3b584f..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinBoatEntityRenderer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.mixin; - -import java.util.Map; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.mojang.datafixers.util.Pair; -import com.terraformersmc.terraform.boat.impl.client.TerraformBoatEntityRenderer; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatHolder; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.render.entity.BoatEntityRenderer; -import net.minecraft.client.render.entity.model.BoatEntityModel; -import net.minecraft.entity.vehicle.BoatEntity; -import net.minecraft.util.Identifier; - -@Mixin(BoatEntityRenderer.class) -@Environment(EnvType.CLIENT) -public class MixinBoatEntityRenderer { - @WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;")) - @SuppressWarnings("unused") - private Object terraformWood$getBoatTextureAndModel(Map> instance, Object type, Operation original, BoatEntity entity) { - //noinspection ConstantConditions - if (entity instanceof TerraformBoatHolder terraformEntity && - (Object) this instanceof TerraformBoatEntityRenderer terraformRenderer) { - return terraformRenderer.getTextureAndModel(terraformEntity); - } - - return original.call(instance, type); - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinEntityPredicate.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinEntityPredicate.java deleted file mode 100644 index fb3b77eb..00000000 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/boat/impl/mixin/MixinEntityPredicate.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.terraformersmc.terraform.boat.impl.mixin; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.terraformersmc.terraform.boat.impl.TerraformBoatInitializer; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; -import net.minecraft.predicate.entity.EntityPredicate; - -@Mixin(EntityPredicate.class) -public class MixinEntityPredicate { - @WrapOperation( - method = "test(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/entity/Entity;)Z", - at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getType()Lnet/minecraft/entity/EntityType;") - ) - private EntityType terraformWood$useVanillaBoatTypeForPredicates(Entity entity, Operation> operation) { - EntityType type = operation.call(entity); - - if (type == TerraformBoatInitializer.BOAT) { - return EntityType.BOAT; - } else if (type == TerraformBoatInitializer.CHEST_BOAT) { - return EntityType.CHEST_BOAT; - } - - return type; - } -} diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/ExtendedLeavesBlock.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/ExtendedLeavesBlock.java index 714e4027..80fce3e5 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/ExtendedLeavesBlock.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/ExtendedLeavesBlock.java @@ -12,8 +12,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockView; import net.minecraft.world.WorldAccess; +import net.minecraft.world.WorldView; +import net.minecraft.world.tick.ScheduledTickView; /** * A leaves block with extended range, permitting leaves to be as far as 13 blocks away from the tree rather than the @@ -50,19 +51,19 @@ public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Ran } @Override - public int getOpacity(BlockState state, BlockView view, BlockPos pos) { + public int getOpacity(BlockState state) { return 0; } @Override - public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + public BlockState getStateForNeighborUpdate(BlockState state, WorldView world, ScheduledTickView tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, Random random) { if (state.get(WATERLOGGED)) { - world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + tickView.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); } int distance = ExtendedLeavesBlock.getDistanceFromLog(neighborState) + 1; if (distance != 1 || state.get(DISTANCE) != distance) { - world.scheduleBlockTick(pos, this, 1); + tickView.scheduleBlockTick(pos, this, 1); } return state; diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/LeafPileBlock.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/LeafPileBlock.java index 17acd5e5..4488fb2a 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/LeafPileBlock.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/LeafPileBlock.java @@ -7,10 +7,11 @@ import net.minecraft.registry.tag.FluidTags; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.BlockView; -import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldView; +import net.minecraft.world.tick.ScheduledTickView; /** * A very thin block that is intended to be used like a carpet block, but for leaves. @@ -28,8 +29,8 @@ public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos } @Override - public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighbor) { - return !state.canPlaceAt(world, pos) ? Blocks.AIR.getDefaultState() : super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighbor); + public BlockState getStateForNeighborUpdate(BlockState state, WorldView world, ScheduledTickView tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, Random random) { + return !state.canPlaceAt(world, pos) ? Blocks.AIR.getDefaultState() : super.getStateForNeighborUpdate(state, world, tickView, pos, direction, neighborPos, neighborState, random); } @Override diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/TransparentLeavesBlock.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/TransparentLeavesBlock.java index 517e8f6d..466b6ba1 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/TransparentLeavesBlock.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/leaves/api/block/TransparentLeavesBlock.java @@ -3,8 +3,6 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.LeavesBlock; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; /** * A leaf block that does not block light. @@ -15,7 +13,7 @@ public TransparentLeavesBlock(Block.Settings settings) { } @Override - public int getOpacity(BlockState state, BlockView view, BlockPos pos) { + public int getOpacity(BlockState state) { return 0; } } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/sign/impl/mixin/MixinSignEditScreen.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/sign/impl/mixin/MixinSignEditScreen.java index 14879e0e..7e8a7aa9 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/sign/impl/mixin/MixinSignEditScreen.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/sign/impl/mixin/MixinSignEditScreen.java @@ -7,7 +7,9 @@ import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; import net.minecraft.block.WoodType; +import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen; import net.minecraft.client.gui.screen.ingame.SignEditScreen; import net.minecraft.client.render.TexturedRenderLayers; import net.minecraft.client.util.SpriteIdentifier; @@ -16,13 +18,20 @@ @Mixin(SignEditScreen.class) @Environment(EnvType.CLIENT) -public class MixinSignEditScreen { +public abstract class MixinSignEditScreen extends AbstractSignEditScreen { + public MixinSignEditScreen(SignBlockEntity blockEntity, boolean front, boolean filtered) { + super(blockEntity, front, filtered); + } + @WrapOperation( - method = "renderSignBackground", + // DrawContext#draw callback within the renderSignBackground method + method = "method_64048", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/TexturedRenderLayers;getSignTextureId(Lnet/minecraft/block/WoodType;)Lnet/minecraft/client/util/SpriteIdentifier;") ) @SuppressWarnings("unused") - private SpriteIdentifier terraformWood$editSignTextureId(WoodType type, Operation original, DrawContext drawContext, BlockState state) { + private SpriteIdentifier terraformWood$editSignTextureId(WoodType type, Operation original, DrawContext drawContext) { + BlockState state = this.blockEntity.getCachedState(); + if (state.getBlock() instanceof TerraformSign signBlock) { return new SpriteIdentifier(TexturedRenderLayers.SIGNS_ATLAS_TEXTURE, signBlock.getTexture()); } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/BareSmallLogBlock.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/BareSmallLogBlock.java index 12fa9d2d..65d27243 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/BareSmallLogBlock.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/BareSmallLogBlock.java @@ -318,7 +318,7 @@ public BlockState getNeighborUpdateState(BlockState state, Direction fromDirecti } @Override - public boolean isTransparent(BlockState state, BlockView world, BlockPos pos) { + public boolean isTransparent(BlockState state) { return !state.get(WATERLOGGED); } diff --git a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/SmallLogBlock.java b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/SmallLogBlock.java index 007ff130..143d2acb 100644 --- a/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/SmallLogBlock.java +++ b/terraform-wood-api-v1/src/main/java/com/terraformersmc/terraform/wood/api/block/SmallLogBlock.java @@ -206,7 +206,7 @@ public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos p } @Override - public VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos pos) { + public VoxelShape getCullingShape(BlockState state) { return this.collisionShapes[this.getShapeIndex(state)]; } diff --git a/terraform-wood-api-v1/src/main/resources/fabric.mod.json b/terraform-wood-api-v1/src/main/resources/fabric.mod.json index 6dc2c4b7..11690734 100644 --- a/terraform-wood-api-v1/src/main/resources/fabric.mod.json +++ b/terraform-wood-api-v1/src/main/resources/fabric.mod.json @@ -6,10 +6,8 @@ "environment": "*", "entrypoints": { "main": [ - "com.terraformersmc.terraform.boat.impl.TerraformBoatInitializer" ], "client": [ - "com.terraformersmc.terraform.boat.impl.client.TerraformBoatClientInitializer" ] }, "license": "LGPL-3.0-only", @@ -60,7 +58,6 @@ } }, "mixins": [ - "mixins.terraform-boats.json", "mixins.terraform-leaves.json", "mixins.terraform-signs.json", "mixins.terraform-wood.json" diff --git a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTest.java b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTest.java index 4a792c54..dec09ee6 100644 --- a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTest.java +++ b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTest.java @@ -1,28 +1,23 @@ package com.terraformersmc.terraform.wood.test; -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper; import com.terraformersmc.terraform.sign.api.block.TerraformHangingSignBlock; import com.terraformersmc.terraform.sign.api.block.TerraformSignBlock; import com.terraformersmc.terraform.sign.api.block.TerraformWallHangingSignBlock; import com.terraformersmc.terraform.sign.api.block.TerraformWallSignBlock; -import com.terraformersmc.terraform.wood.test.command.SpawnBoatsCommand; +import com.terraformersmc.terraform.wood.test.command.SpawnBoatsCommand; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.minecraft.block.AbstractBlock; import net.minecraft.block.Block; import net.minecraft.block.Blocks; -import net.minecraft.item.HangingSignItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroups; -import net.minecraft.item.Items; -import net.minecraft.item.SignItem; +import net.minecraft.item.*; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; @@ -31,13 +26,7 @@ public class TerraformWoodTest implements ModInitializer { private static final Identifier CUSTOM_PLANKS_ID = Identifier.of(MOD_ID, "custom_planks"); - protected static final Identifier CUSTOM_BOAT_ID = Identifier.of(MOD_ID, "custom_boat"); - private static final Identifier CUSTOM_CHEST_BOAT_ID = Identifier.of(MOD_ID, "custom_chest_boat"); - protected static final Identifier CUSTOM_RAFT_ID = Identifier.of(MOD_ID, "custom_raft"); - private static final Identifier CUSTOM_CHEST_RAFT_ID = Identifier.of(MOD_ID, "custom_chest_raft"); - - public static final RegistryKey CUSTOM_BOAT_KEY = TerraformBoatTypeRegistry.createKey(CUSTOM_BOAT_ID); - public static final RegistryKey CUSTOM_RAFT_KEY = TerraformBoatTypeRegistry.createKey(CUSTOM_RAFT_ID); + public static final Identifier CUSTOM_BOATS_ID = Identifier.of(MOD_ID, "custom"); protected static final Identifier SIGN_TEXTURE_ID = Identifier.of(MOD_ID, "entity/signs/custom"); protected static final Identifier HANGING_SIGN_TEXTURE_ID = Identifier.of(MOD_ID, "entity/signs/hanging/custom"); @@ -47,63 +36,52 @@ public class TerraformWoodTest implements ModInitializer { private static final Identifier CUSTOM_HANGING_SIGN_ID = Identifier.of(MOD_ID, "custom_hanging_sign"); private static final Identifier CUSTOM_WALL_HANGING_SIGN_ID = Identifier.of(MOD_ID, "custom_wall_hanging_sign"); + public static BoatItem customBoatItem; + public static BoatItem customChestBoatItem; + public static BoatItem customRaftItem; + public static BoatItem customChestRaftItem; + @Override public void onInitialize() { - Item planks = new Item(new Item.Settings()); + Item planks = new Item(new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, CUSTOM_PLANKS_ID))); // Boats - Item boatItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_BOAT_ID, CUSTOM_BOAT_KEY, false); - Item chestBoatItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_CHEST_BOAT_ID, CUSTOM_BOAT_KEY, true); + customBoatItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_BOATS_ID, false); + customChestBoatItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_BOATS_ID, true); - Item raftItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_RAFT_ID, CUSTOM_RAFT_KEY, false); - Item chestRaftItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_CHEST_RAFT_ID, CUSTOM_RAFT_KEY, true); - - TerraformBoatType boat = new TerraformBoatType.Builder() - .item(boatItem) - .chestItem(chestBoatItem) - .planks(planks) - .build(); - - TerraformBoatType raft = new TerraformBoatType.Builder() - .raft() - .item(raftItem) - .chestItem(chestRaftItem) - .planks(planks) - .build(); + customRaftItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_BOATS_ID, false, true); + customChestRaftItem = TerraformBoatItemHelper.registerBoatItem(CUSTOM_BOATS_ID, true, true); // Signs - Block sign = new TerraformSignBlock(SIGN_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_SIGN).sounds(BlockSoundGroup.ANVIL)); + Block sign = new TerraformSignBlock(SIGN_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_SIGN).sounds(BlockSoundGroup.ANVIL).registryKey(RegistryKey.of(RegistryKeys.BLOCK, CUSTOM_SIGN_ID))); Registry.register(Registries.BLOCK, CUSTOM_SIGN_ID, sign); - Block wallSign = new TerraformWallSignBlock(SIGN_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_WALL_SIGN).sounds(BlockSoundGroup.SAND).dropsLike(sign)); + Block wallSign = new TerraformWallSignBlock(SIGN_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_WALL_SIGN).sounds(BlockSoundGroup.SAND).lootTable(sign.getLootTableKey()).registryKey(RegistryKey.of(RegistryKeys.BLOCK, CUSTOM_WALL_SIGN_ID))); Registry.register(Registries.BLOCK, CUSTOM_WALL_SIGN_ID, wallSign); - Block hangingSign = new TerraformHangingSignBlock(HANGING_SIGN_TEXTURE_ID, HANGING_SIGN_GUI_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN).sounds(BlockSoundGroup.WOOL)); + Block hangingSign = new TerraformHangingSignBlock(HANGING_SIGN_TEXTURE_ID, HANGING_SIGN_GUI_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN).sounds(BlockSoundGroup.WOOL).registryKey(RegistryKey.of(RegistryKeys.BLOCK, CUSTOM_HANGING_SIGN_ID))); Registry.register(Registries.BLOCK, CUSTOM_HANGING_SIGN_ID, hangingSign); - Block wallHangingSign = new TerraformWallHangingSignBlock(HANGING_SIGN_TEXTURE_ID, HANGING_SIGN_GUI_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_WALL_HANGING_SIGN).sounds(BlockSoundGroup.SCULK_SENSOR).dropsLike(hangingSign)); + Block wallHangingSign = new TerraformWallHangingSignBlock(HANGING_SIGN_TEXTURE_ID, HANGING_SIGN_GUI_TEXTURE_ID, AbstractBlock.Settings.copy(Blocks.OAK_WALL_HANGING_SIGN).sounds(BlockSoundGroup.SCULK_SENSOR).lootTable(hangingSign.getLootTableKey()).registryKey(RegistryKey.of(RegistryKeys.BLOCK, CUSTOM_WALL_HANGING_SIGN_ID))); Registry.register(Registries.BLOCK, CUSTOM_WALL_HANGING_SIGN_ID, wallHangingSign); - Item signItem = new SignItem(new Item.Settings().maxCount(16), sign, wallSign); - Item hangingSignItem = new HangingSignItem(hangingSign, wallHangingSign, new Item.Settings().maxCount(16)); + Item signItem = new SignItem(sign, wallSign, new Item.Settings().maxCount(16).registryKey(RegistryKey.of(RegistryKeys.ITEM, CUSTOM_SIGN_ID))); + Item hangingSignItem = new HangingSignItem(hangingSign, wallHangingSign, new Item.Settings().maxCount(16).registryKey(RegistryKey.of(RegistryKeys.ITEM, CUSTOM_HANGING_SIGN_ID))); // Register - Registry.register(TerraformBoatTypeRegistry.INSTANCE, CUSTOM_BOAT_KEY, boat); - Registry.register(TerraformBoatTypeRegistry.INSTANCE, CUSTOM_RAFT_KEY, raft); - Registry.register(Registries.ITEM, CUSTOM_PLANKS_ID, planks); Registry.register(Registries.ITEM, CUSTOM_SIGN_ID, signItem); Registry.register(Registries.ITEM, CUSTOM_HANGING_SIGN_ID, hangingSignItem); ItemGroupEvents.modifyEntriesEvent(ItemGroups.BUILDING_BLOCKS).register(entries -> { entries.addAfter(Items.MANGROVE_PLANKS, planks); - entries.addAfter(Items.MANGROVE_CHEST_BOAT, boatItem, chestBoatItem, raftItem, chestRaftItem); + entries.addAfter(Items.MANGROVE_CHEST_BOAT, customBoatItem, customChestBoatItem, customRaftItem, customChestRaftItem); entries.addAfter(Items.MANGROVE_HANGING_SIGN, signItem, hangingSignItem); }); // Utility commands - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - SpawnBoatsCommand.register(dispatcher); - }); + CommandRegistrationCallback.EVENT.register( + (dispatcher, registryAccess, environment) -> SpawnBoatsCommand.register(dispatcher) + ); } } diff --git a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTestClient.java b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTestClient.java index f72697b8..c8c39b77 100644 --- a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTestClient.java +++ b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/TerraformWoodTestClient.java @@ -7,7 +7,6 @@ public class TerraformWoodTestClient implements ClientModInitializer { @Override public void onInitializeClient() { - TerraformBoatClientHelper.registerModelLayers(TerraformWoodTest.CUSTOM_BOAT_ID, false); - TerraformBoatClientHelper.registerModelLayers(TerraformWoodTest.CUSTOM_RAFT_ID, true); + TerraformBoatClientHelper.registerModelLayers(TerraformWoodTest.CUSTOM_BOATS_ID); } } diff --git a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/command/SpawnBoatsCommand.java b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/command/SpawnBoatsCommand.java index 1dd7ece7..d823d29a 100644 --- a/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/command/SpawnBoatsCommand.java +++ b/terraform-wood-api-v1/src/testmod/java/com/terraformersmc/terraform/wood/test/command/SpawnBoatsCommand.java @@ -3,9 +3,7 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; -import com.terraformersmc.terraform.boat.api.TerraformBoatType; -import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; -import com.terraformersmc.terraform.boat.impl.entity.TerraformBoatEntity; +import com.terraformersmc.terraform.boat.impl.data.TerraformBoatData; import com.terraformersmc.terraform.wood.test.TerraformWoodTest; import net.minecraft.advancement.AdvancementEntry; @@ -15,6 +13,10 @@ import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.ShulkerEntity; import net.minecraft.entity.passive.GoatEntity; +import net.minecraft.entity.vehicle.BoatEntity; +import net.minecraft.entity.vehicle.ChestBoatEntity; +import net.minecraft.entity.vehicle.ChestRaftEntity; +import net.minecraft.entity.vehicle.RaftEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -39,8 +41,7 @@ private static int execute(CommandContext context) { ServerWorld world = source.getWorld(); Vec3d pos = source.getPosition(); - TerraformBoatType boatType = TerraformBoatTypeRegistry.INSTANCE.getOrThrow(TerraformWoodTest.CUSTOM_BOAT_KEY); - TerraformBoatType raftType = TerraformBoatTypeRegistry.INSTANCE.getOrThrow(TerraformWoodTest.CUSTOM_RAFT_KEY); + TerraformBoatData boatData = TerraformBoatData.get(TerraformWoodTest.CUSTOM_BOATS_ID); // Revoke advancement ServerPlayerEntity player = source.getPlayer(); @@ -60,20 +61,20 @@ private static int execute(CommandContext context) { } // Spawn boats - TerraformBoatEntity boat = new TerraformBoatEntity(world, pos.getX(), pos.getY(), pos.getZ()); - boat.setTerraformBoat(boatType); + BoatEntity boat = new BoatEntity(boatData.boatEntity(), world, () -> TerraformWoodTest.customBoatItem); + boat.setPos(pos.getX(), pos.getY(), pos.getZ()); world.spawnEntity(boat); - TerraformBoatEntity chestBoat = new TerraformBoatEntity(world, pos.getX() - 2, pos.getY(), pos.getZ()); - chestBoat.setTerraformBoat(boatType); + ChestBoatEntity chestBoat = new ChestBoatEntity(boatData.chestBoatEntity(), world, () -> TerraformWoodTest.customChestBoatItem); + chestBoat.setPos(pos.getX() - 2, pos.getY(), pos.getZ()); world.spawnEntity(chestBoat); - TerraformBoatEntity raft = new TerraformBoatEntity(world, pos.getX() - 4, pos.getY(), pos.getZ()); - raft.setTerraformBoat(raftType); + RaftEntity raft = new RaftEntity(boatData.raftEntity(), world, () -> TerraformWoodTest.customRaftItem); + raft.setPos(pos.getX() - 4, pos.getY(), pos.getZ()); world.spawnEntity(raft); - TerraformBoatEntity chestRaft = new TerraformBoatEntity(world, pos.getX() - 6, pos.getY(), pos.getZ()); - chestRaft.setTerraformBoat(raftType); + ChestRaftEntity chestRaft = new ChestRaftEntity(boatData.chestRaftEntity(), world, () -> TerraformWoodTest.customChestRaftItem); + chestRaft.setPos(pos.getX() - 6, pos.getY(), pos.getZ()); world.spawnEntity(chestRaft); // Spawn passengers diff --git a/terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/boat/custom_boat.png b/terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/boat/custom.png similarity index 100% rename from terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/boat/custom_boat.png rename to terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/boat/custom.png diff --git a/terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/chest_boat/custom_boat.png b/terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/chest_boat/custom.png similarity index 100% rename from terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/chest_boat/custom_boat.png rename to terraform-wood-api-v1/src/testmod/resources/assets/terraform/textures/entity/chest_boat/custom.png