From 95ca694d0689c54d5744001c39c7ae0c015b45c8 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Wed, 18 Sep 2024 20:45:44 -0600 Subject: [PATCH] Wood Recipes and Boats (#1980) --- .../resources/assets/gtceu/lang/en_ud.json | 6 + .../resources/assets/gtceu/lang/en_us.json | 6 + .../assets/gtceu/models/item/rubber_boat.json | 6 + .../gtceu/models/item/rubber_chest_boat.json | 6 + .../gtceu/models/item/treated_wood_boat.json | 6 + .../models/item/treated_wood_chest_boat.json | 6 + .../gregtechceu/gtceu/client/ClientProxy.java | 14 ++ .../renderer/entity/GTBoatRenderer.java | 60 +++++++ .../gtceu/common/data/GTBlocks.java | 1 + .../gtceu/common/data/GTEntityTypes.java | 16 +- .../gtceu/common/data/GTItems.java | 22 +++ .../gtceu/common/data/GTMaterials.java | 1 + .../gtceu/common/entity/GTBoat.java | 123 +++++++++++++ .../gtceu/common/entity/GTChestBoat.java | 71 ++++++++ .../gtceu/common/item/GTBoatItem.java | 91 ++++++++++ .../item/GTBoatItemDispenseBehaviour.java | 72 ++++++++ .../gtceu/data/recipe/WoodTypeEntry.java | 45 +++++ .../data/recipe/misc/WoodMachineRecipes.java | 163 +++++++++++++++--- .../resources/META-INF/accesstransformer.cfg | 2 + .../textures/entity/boat/rubber_boat.png | Bin 0 -> 2872 bytes .../entity/boat/rubber_chest_boat.png | Bin 0 -> 4731 bytes .../textures/entity/boat/treated_boat.png | Bin 0 -> 2845 bytes .../entity/boat/treated_chest_boat.png | Bin 0 -> 4714 bytes .../gtceu/textures/item/rubber_boat.png | Bin 0 -> 614 bytes .../gtceu/textures/item/rubber_chest_boat.png | Bin 0 -> 635 bytes .../gtceu/textures/item/treated_wood_boat.png | Bin 0 -> 556 bytes .../textures/item/treated_wood_chest_boat.png | Bin 0 -> 621 bytes 27 files changed, 692 insertions(+), 25 deletions(-) create mode 100644 src/generated/resources/assets/gtceu/models/item/rubber_boat.json create mode 100644 src/generated/resources/assets/gtceu/models/item/rubber_chest_boat.json create mode 100644 src/generated/resources/assets/gtceu/models/item/treated_wood_boat.json create mode 100644 src/generated/resources/assets/gtceu/models/item/treated_wood_chest_boat.json create mode 100644 src/main/java/com/gregtechceu/gtceu/client/renderer/entity/GTBoatRenderer.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/entity/GTBoat.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/entity/GTChestBoat.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItem.java create mode 100644 src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItemDispenseBehaviour.java create mode 100644 src/main/resources/assets/gtceu/textures/entity/boat/rubber_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/entity/boat/rubber_chest_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/entity/boat/treated_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/entity/boat/treated_chest_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/item/rubber_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/item/rubber_chest_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/item/treated_wood_boat.png create mode 100644 src/main/resources/assets/gtceu/textures/item/treated_wood_chest_boat.png diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index add14c8f1b..f0ccff0fc4 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -2586,6 +2586,8 @@ "enchantment.gtceu.disjunction.desc": "˙sqoɯ pǝʇɐןǝɹ-ɹǝpuƎ oʇ ssǝuʍoןS puɐ ssǝuʞɐǝM sǝıןddⱯ", "enchantment.gtceu.hard_hammer.desc": "˙ɹǝɯɯɐH ɥɔǝ⟘bǝɹ⅁ ɐ ɥʇıʍ pǝuıɯ ǝɹǝʍ ʎǝɥʇ ɟı sɐ sʞɔoןq sʞɐǝɹᗺ", "enchantment.hard_hammer": "buıɹǝɯɯɐH", + "entity.gtceu.boat": "ʇɐoᗺ", + "entity.gtceu.chest_boat": "ʇɐoᗺ ʇsǝɥƆ", "entity.gtceu.dynamite": "ǝʇıɯɐuʎᗡ", "entity.gtceu.industrial_tnt": "⟘N⟘ ןɐıɹʇsnpuI", "entity.gtceu.powderbarrel": "ןǝɹɹɐqɹǝpʍoԀ", @@ -4716,6 +4718,8 @@ "item.gtceu.rotor_casting_mold.tooltip": "sɹoʇoᴚ buıʞɐɯ ɹoɟ pןoWㄥ§", "item.gtceu.rotor_extruder_mold": ")ɹoʇoᴚ( pןoW ɹǝpnɹʇxƎ", "item.gtceu.rotor_extruder_mold.tooltip": "sɹoʇoᴚ buıʞɐɯ ɹoɟ ǝdɐɥS ɹǝpnɹʇxƎㄥ§", + "item.gtceu.rubber_boat": "ʇɐoᗺ ɹǝqqnᴚ", + "item.gtceu.rubber_chest_boat": "ʇsǝɥƆ ɥʇıʍ ʇɐoᗺ ɹǝqqnᴚ", "item.gtceu.rubber_gloves": "sǝʌoן⅁ ɹǝqqnᴚ", "item.gtceu.salt_dust": "ʇןɐS", "item.gtceu.saw_extruder_mold.tooltip": "sʍɐS buıʞɐɯ ɹoɟ ǝdɐɥS ɹǝpnɹʇxƎㄥ§", @@ -4928,7 +4932,9 @@ "item.gtceu.tool.wrench.tooltip": "sǝuıɥɔɐW ǝןʇuɐɯsıp oʇ ʞɔıןɔ ʇɟǝן pןoH8§", "item.gtceu.transistor": "ɹoʇsısuɐɹ⟘", "item.gtceu.transistor.tooltip": "ʇuǝuodɯoƆ ɔıuoɹʇɔǝןƎ ɔısɐᗺㄥ§", + "item.gtceu.treated_wood_boat": "ʇɐoᗺ pooM pǝʇɐǝɹ⟘", "item.gtceu.treated_wood_bolt": "ʞɔıʇS pooM pǝʇɐǝɹ⟘ ʇɹoɥS", + "item.gtceu.treated_wood_chest_boat": "ʇsǝɥƆ ɥʇıʍ ʇɐoᗺ pooM pǝʇɐǝɹ⟘", "item.gtceu.treated_wood_dust": "dןnԀ pooM pǝʇɐǝɹ⟘", "item.gtceu.treated_wood_plate": "ʞuɐןԀ pooM pǝʇɐǝɹ⟘", "item.gtceu.treated_wood_rod": "ʞɔıʇS pooM pǝʇɐǝɹ⟘", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 7c1eb46ed9..08b1471817 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -2586,6 +2586,8 @@ "enchantment.gtceu.disjunction.desc": "Applies Weakness and Slowness to Ender-related mobs.", "enchantment.gtceu.hard_hammer.desc": "Breaks blocks as if they were mined with a GregTech Hammer.", "enchantment.hard_hammer": "Hammering", + "entity.gtceu.boat": "Boat", + "entity.gtceu.chest_boat": "Chest Boat", "entity.gtceu.dynamite": "Dynamite", "entity.gtceu.industrial_tnt": "Industrial TNT", "entity.gtceu.powderbarrel": "Powderbarrel", @@ -4716,6 +4718,8 @@ "item.gtceu.rotor_casting_mold.tooltip": "§7Mold for making Rotors", "item.gtceu.rotor_extruder_mold": "Extruder Mold (Rotor)", "item.gtceu.rotor_extruder_mold.tooltip": "§7Extruder Shape for making Rotors", + "item.gtceu.rubber_boat": "Rubber Boat", + "item.gtceu.rubber_chest_boat": "Rubber Boat with Chest", "item.gtceu.rubber_gloves": "Rubber Gloves", "item.gtceu.salt_dust": "Salt", "item.gtceu.saw_extruder_mold.tooltip": "§7Extruder Shape for making Saws", @@ -4928,7 +4932,9 @@ "item.gtceu.tool.wrench.tooltip": "§8Hold left click to dismantle Machines", "item.gtceu.transistor": "Transistor", "item.gtceu.transistor.tooltip": "§7Basic Electronic Component", + "item.gtceu.treated_wood_boat": "Treated Wood Boat", "item.gtceu.treated_wood_bolt": "Short Treated Wood Stick", + "item.gtceu.treated_wood_chest_boat": "Treated Wood Boat with Chest", "item.gtceu.treated_wood_dust": "Treated Wood Pulp", "item.gtceu.treated_wood_plate": "Treated Wood Plank", "item.gtceu.treated_wood_rod": "Treated Wood Stick", diff --git a/src/generated/resources/assets/gtceu/models/item/rubber_boat.json b/src/generated/resources/assets/gtceu/models/item/rubber_boat.json new file mode 100644 index 0000000000..1298fccf6d --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/rubber_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/rubber_boat" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/rubber_chest_boat.json b/src/generated/resources/assets/gtceu/models/item/rubber_chest_boat.json new file mode 100644 index 0000000000..69a0964968 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/rubber_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/rubber_chest_boat" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/treated_wood_boat.json b/src/generated/resources/assets/gtceu/models/item/treated_wood_boat.json new file mode 100644 index 0000000000..2ad82d61dc --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/treated_wood_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/treated_wood_boat" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/treated_wood_chest_boat.json b/src/generated/resources/assets/gtceu/models/item/treated_wood_chest_boat.json new file mode 100644 index 0000000000..c24d335945 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/treated_wood_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/treated_wood_chest_boat" + } +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java index c1f7f35e7e..336acbcfc7 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java +++ b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java @@ -8,22 +8,27 @@ import com.gregtechceu.gtceu.api.gui.compass.GTRecipeViewCreator; import com.gregtechceu.gtceu.api.gui.compass.MultiblockAction; import com.gregtechceu.gtceu.client.particle.HazardParticle; +import com.gregtechceu.gtceu.client.renderer.entity.GTBoatRenderer; import com.gregtechceu.gtceu.client.renderer.entity.GTExplosiveRenderer; import com.gregtechceu.gtceu.common.CommonProxy; import com.gregtechceu.gtceu.common.data.GTBlockEntities; import com.gregtechceu.gtceu.common.data.GTEntityTypes; import com.gregtechceu.gtceu.common.data.GTParticleTypes; +import com.gregtechceu.gtceu.common.entity.GTBoat; import com.gregtechceu.gtceu.utils.input.KeyBind; import com.lowdragmc.lowdraglib.gui.compass.CompassManager; import com.lowdragmc.lowdraglib.gui.compass.component.RecipeComponent; +import net.minecraft.client.model.BoatModel; +import net.minecraft.client.model.ChestBoatModel; import net.minecraft.client.renderer.blockentity.HangingSignRenderer; import net.minecraft.client.renderer.blockentity.SignRenderer; import net.minecraft.client.renderer.entity.ThrownItemRenderer; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.RegisterGuiOverlaysEvent; import net.minecraftforge.client.event.RegisterKeyMappingsEvent; @@ -64,6 +69,15 @@ public void onRegisterEntityRenderers(EntityRenderersEvent.RegisterRenderers eve event.registerBlockEntityRenderer(GTBlockEntities.GT_SIGN.get(), SignRenderer::new); event.registerBlockEntityRenderer(GTBlockEntities.GT_HANGING_SIGN.get(), HangingSignRenderer::new); + + event.registerEntityRenderer(GTEntityTypes.BOAT.get(), c -> new GTBoatRenderer(c, false)); + event.registerEntityRenderer(GTEntityTypes.CHEST_BOAT.get(), c -> new GTBoatRenderer(c, true)); + + for (var type : GTBoat.BoatType.values()) { + ForgeHooksClient.registerLayerDefinition(GTBoatRenderer.getBoatModelName(type), BoatModel::createBodyModel); + ForgeHooksClient.registerLayerDefinition(GTBoatRenderer.getChestBoatModelName(type), + ChestBoatModel::createBodyModel); + } } @SubscribeEvent diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/entity/GTBoatRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/entity/GTBoatRenderer.java new file mode 100644 index 0000000000..f5b3d71d55 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/entity/GTBoatRenderer.java @@ -0,0 +1,60 @@ +package com.gregtechceu.gtceu.client.renderer.entity; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.common.entity.GTBoat; +import com.gregtechceu.gtceu.common.entity.GTChestBoat; + +import net.minecraft.client.model.BoatModel; +import net.minecraft.client.model.ChestBoatModel; +import net.minecraft.client.model.ListModel; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.entity.BoatRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.vehicle.Boat; + +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.util.Pair; + +import java.util.Map; +import java.util.stream.Stream; + +public class GTBoatRenderer extends BoatRenderer { + + private final Map>> boats; + + public GTBoatRenderer(EntityRendererProvider.Context context, boolean chestBoat) { + super(context, chestBoat); + boats = Stream.of(GTBoat.BoatType.values()).collect(ImmutableMap.toImmutableMap(k -> k, + (m) -> Pair.of(new ResourceLocation(GTCEu.MOD_ID, + getTextureLocation(m, chestBoat)), createBoatModel(context, m, chestBoat)))); + } + + @Override + public Pair> getModelWithLocation(Boat boat) { + if (boat instanceof GTChestBoat gtcb) { + return this.boats.get(gtcb.getBoatType()); + } else + return this.boats.get(((GTBoat) boat).getBoatType()); + } + + private static String getTextureLocation(GTBoat.BoatType type, boolean chest) { + return chest ? "textures/entity/boat/" + type.getName() + "_chest_boat.png" : + "textures/entity/boat/" + type.getName() + "_boat.png"; + } + + private BoatModel createBoatModel(EntityRendererProvider.Context context, GTBoat.BoatType type, boolean chest) { + ModelLayerLocation modelLoc = chest ? getChestBoatModelName(type) : getBoatModelName(type); + ModelPart part = context.bakeLayer(modelLoc); + return chest ? new ChestBoatModel(part) : new BoatModel(part); + } + + public static ModelLayerLocation getChestBoatModelName(GTBoat.BoatType type) { + return new ModelLayerLocation(new ResourceLocation(GTCEu.MOD_ID, "chest_boat/" + type.getName()), "main"); + } + + public static ModelLayerLocation getBoatModelName(GTBoat.BoatType type) { + return new ModelLayerLocation(new ResourceLocation(GTCEu.MOD_ID, "boat/" + type.getName()), "main"); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java index efdfa08f54..3d1c611ff9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java @@ -1298,6 +1298,7 @@ public static ItemColor leavesItemColor() { .tag(ItemTags.WOODEN_FENCES) .build() .register(); + public static final BlockEntry TREATED_WOOD_SIGN = REGISTRATE .block("treated_wood_sign", (p) -> new GTStandingSignBlock(p, TREATED_WOOD_TYPE)) .initialProperties(() -> Blocks.SPRUCE_SIGN) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTEntityTypes.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTEntityTypes.java index 13a09ffdcf..5a7d473cce 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTEntityTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTEntityTypes.java @@ -1,8 +1,6 @@ package com.gregtechceu.gtceu.common.data; -import com.gregtechceu.gtceu.common.entity.DynamiteEntity; -import com.gregtechceu.gtceu.common.entity.IndustrialTNTEntity; -import com.gregtechceu.gtceu.common.entity.PowderbarrelEntity; +import com.gregtechceu.gtceu.common.entity.*; import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.entity.MobCategory; @@ -32,5 +30,17 @@ public class GTEntityTypes { .properties(builder -> builder.sized(0.98F, 0.98F).fireImmune().clientTrackingRange(10).updateInterval(10)) .register(); + public static final EntityEntry BOAT = REGISTRATE + .entity("boat", GTBoat::new, MobCategory.MISC) + .lang("Boat") + .properties(builder -> builder.sized(1.375f, 0.5625f).clientTrackingRange(10)) + .register(); + + public static final EntityEntry CHEST_BOAT = REGISTRATE + .entity("chest_boat", GTChestBoat::new, MobCategory.MISC) + .lang("Chest Boat") + .properties(builder -> builder.sized(1.375f, 0.5625f).clientTrackingRange(10)) + .register(); + public static void init() {} } diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java index 92ed72be06..167fa50dd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTItems.java @@ -31,6 +31,7 @@ import com.gregtechceu.gtceu.api.registry.registrate.CompassSection; import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; import com.gregtechceu.gtceu.common.data.materials.GTFoods; +import com.gregtechceu.gtceu.common.entity.GTBoat; import com.gregtechceu.gtceu.common.item.*; import com.gregtechceu.gtceu.common.item.armor.*; import com.gregtechceu.gtceu.common.item.tool.behavior.LighterBehavior; @@ -2698,6 +2699,27 @@ public Component getItemName(ItemStack stack) { public static ItemEntry BLACKLIGHT = REGISTRATE.item("blacklight", Item::new) .onRegister(compassNode(GTCompassSections.MISC)).register(); + public static ItemEntry RUBBER_BOAT = REGISTRATE + .item("rubber_boat", p -> new GTBoatItem(false, GTBoat.BoatType.RUBBER, new Item.Properties())) + .lang("Rubber Boat") + .register(); + + public static ItemEntry TREATED_WOOD_BOAT = REGISTRATE + .item("treated_wood_boat", p -> new GTBoatItem(false, GTBoat.BoatType.TREATED_WOOD, new Item.Properties())) + .lang("Treated Wood Boat") + .register(); + + public static ItemEntry RUBBER_CHEST_BOAT = REGISTRATE + .item("rubber_chest_boat", p -> new GTBoatItem(true, GTBoat.BoatType.RUBBER, new Item.Properties())) + .lang("Rubber Boat with Chest") + .register(); + + public static ItemEntry TREATED_WOOD_CHEST_BOAT = REGISTRATE + .item("treated_wood_chest_boat", + p -> new GTBoatItem(true, GTBoat.BoatType.TREATED_WOOD, new Item.Properties())) + .lang("Treated Wood Boat with Chest") + .register(); + public static void init() { generateMaterialItems(); generateTools(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java index 224eaf27af..1119778619 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java @@ -123,6 +123,7 @@ public static void init() { ingot.setIgnored(Iron, Items.IRON_INGOT); ingot.setIgnored(Gold, Items.GOLD_INGOT); ingot.setIgnored(Copper, Items.COPPER_INGOT); + ingot.setIgnored(Brick, Items.BRICK); ingot.setIgnored(Wax, Items.HONEYCOMB); nugget.setIgnored(Gold, Items.GOLD_NUGGET); diff --git a/src/main/java/com/gregtechceu/gtceu/common/entity/GTBoat.java b/src/main/java/com/gregtechceu/gtceu/common/entity/GTBoat.java new file mode 100644 index 0000000000..6986a26b67 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/entity/GTBoat.java @@ -0,0 +1,123 @@ +package com.gregtechceu.gtceu.common.entity; + +import com.gregtechceu.gtceu.common.data.GTBlocks; +import com.gregtechceu.gtceu.common.data.GTEntityTypes; +import com.gregtechceu.gtceu.common.data.GTItems; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; + +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +public class GTBoat extends Boat { + + public GTBoat(EntityType entityType, Level level) { + super(entityType, level); + this.blocksBuilding = true; + } + + public GTBoat(Level level, double x, double y, double z) { + super(GTEntityTypes.BOAT.get(), level); + this.setPos(x, y, z); + this.xo = x; + this.yo = y; + this.zo = z; + } + + @Nullable + @Override + public Component getCustomName() { + return super.getCustomName(); + } + + @Override + public Packet getAddEntityPacket() { + return new ClientboundAddEntityPacket(this); + } + + @Override + protected void addAdditionalSaveData(CompoundTag compound) { + compound.putString("Type", getBoatType().getName()); + } + + @Override + protected void readAdditionalSaveData(CompoundTag compound) { + if (compound.contains("Type")) { + entityData.set(DATA_ID_TYPE, BoatType.byName(compound.getString("Type")).ordinal()); + } + } + + @Override + public Item getDropItem() { + return switch (BoatType.byId(this.entityData.get(DATA_ID_TYPE))) { + case RUBBER -> GTItems.RUBBER_BOAT.get(); + case TREATED_WOOD -> GTItems.TREATED_WOOD_BOAT.get(); + }; + } + + public void setBoatType(BoatType type) { + this.entityData.set(DATA_ID_TYPE, type.ordinal()); + } + + public BoatType getBoatType() { + return BoatType.byId(entityData.get(DATA_ID_TYPE)); + } + + @Override + public void setVariant(Type variant) {} + + @Override + public Type getVariant() { + return Type.OAK; + } + + public enum BoatType { + + RUBBER("rubber", GTBlocks.RUBBER_PLANK.get()), + TREATED_WOOD("treated", GTBlocks.TREATED_WOOD_PLANK.get()); + + private final String name; + private final Block planks; + + private static final BoatType[] VALUES = values(); + + private BoatType(String name, Block planks) { + this.name = name; + this.planks = planks; + } + + public String getName() { + return this.name; + } + + public Block getPlanks() { + return this.planks; + } + + public String toString() { + return this.name; + } + + /** + * Get a boat type by its enum ordinal + */ + public static BoatType byId(int id) { + if (id < 0 || id >= VALUES.length) id = 0; + return VALUES[id]; + } + + public static BoatType byName(String name) { + return Arrays.stream(VALUES).filter(type -> type.getName().equals(name)).findFirst().orElse(VALUES[0]); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/entity/GTChestBoat.java b/src/main/java/com/gregtechceu/gtceu/common/entity/GTChestBoat.java new file mode 100644 index 0000000000..81825a0b61 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/entity/GTChestBoat.java @@ -0,0 +1,71 @@ +package com.gregtechceu.gtceu.common.entity; + +import com.gregtechceu.gtceu.common.data.GTEntityTypes; +import com.gregtechceu.gtceu.common.data.GTItems; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.ChestBoat; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; + +public class GTChestBoat extends ChestBoat { + + public GTChestBoat(EntityType entityType, Level level) { + super(entityType, level); + this.blocksBuilding = true; + } + + public GTChestBoat(Level level, double x, double y, double z) { + super(GTEntityTypes.CHEST_BOAT.get(), level); + this.setPos(x, y, z); + this.xo = x; + this.yo = y; + this.zo = z; + } + + @Override + public Packet getAddEntityPacket() { + return new ClientboundAddEntityPacket(this); + } + + @Override + protected void addAdditionalSaveData(CompoundTag compound) { + compound.putString("Type", getBoatType().getName()); + } + + @Override + protected void readAdditionalSaveData(CompoundTag compound) { + if (compound.contains("Type")) { + entityData.set(DATA_ID_TYPE, GTBoat.BoatType.byName(compound.getString("Type")).ordinal()); + } + } + + @Override + public Item getDropItem() { + return switch (GTBoat.BoatType.byId(this.entityData.get(DATA_ID_TYPE))) { + case RUBBER -> GTItems.RUBBER_CHEST_BOAT.get(); + case TREATED_WOOD -> GTItems.TREATED_WOOD_CHEST_BOAT.get(); + }; + } + + public void setBoatType(GTBoat.BoatType type) { + this.entityData.set(DATA_ID_TYPE, type.ordinal()); + } + + public GTBoat.BoatType getBoatType() { + return GTBoat.BoatType.byId(entityData.get(DATA_ID_TYPE)); + } + + @Override + public void setVariant(Type variant) {} + + @Override + public Type getVariant() { + return Type.OAK; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItem.java b/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItem.java new file mode 100644 index 0000000000..945cc8a009 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItem.java @@ -0,0 +1,91 @@ +package com.gregtechceu.gtceu.common.item; + +import com.gregtechceu.gtceu.common.entity.GTBoat; +import com.gregtechceu.gtceu.common.entity.GTChestBoat; + +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; + +import java.util.List; +import java.util.function.Predicate; + +public class GTBoatItem extends Item { + + private static final Predicate ENTITY_PREDICATE = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); + private final GTBoat.BoatType type; + private final boolean hasChest; + + public GTBoatItem(boolean hasChest, GTBoat.BoatType type, Item.Properties properties) { + super(properties); + this.hasChest = hasChest; + this.type = type; + DispenserBlock.registerBehavior(this, new GTBoatItemDispenseBehaviour(type, hasChest)); + } + + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { + ItemStack itemstack = player.getItemInHand(hand); + HitResult hitresult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); + if (hitresult.getType() == HitResult.Type.MISS) { + return InteractionResultHolder.pass(itemstack); + } else { + Vec3 vec3 = player.getViewVector(1.0F); + double d0 = 5.0; + List list = level.getEntities(player, + player.getBoundingBox().expandTowards(vec3.scale(5.0)).inflate(1.0), ENTITY_PREDICATE); + if (!list.isEmpty()) { + Vec3 vec31 = player.getEyePosition(); + for (Entity e : list) { + AABB aabb = e.getBoundingBox().inflate((double) e.getPickRadius()); + if (aabb.contains(vec31)) { + return InteractionResultHolder.pass(itemstack); + } + } + } + + if (hitresult.getType() == HitResult.Type.BLOCK) { + Boat boat; + if (hasChest) { + boat = new GTChestBoat(level, hitresult.getLocation().x, hitresult.getLocation().y, + hitresult.getLocation().z); + ((GTChestBoat) boat).setBoatType(type); + } else { + boat = new GTBoat(level, hitresult.getLocation().x, hitresult.getLocation().y, + hitresult.getLocation().z); + ((GTBoat) boat).setBoatType(type); + } + + boat.setYRot(player.getYRot()); + if (!level.noCollision(boat, boat.getBoundingBox())) { + return InteractionResultHolder.fail(itemstack); + } else { + if (!level.isClientSide) { + level.addFreshEntity(boat); + level.gameEvent(player, GameEvent.ENTITY_PLACE, hitresult.getLocation()); + if (!player.getAbilities().instabuild) { + itemstack.shrink(1); + } + } + + player.awardStat(Stats.ITEM_USED.get(this)); + return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + } else { + return InteractionResultHolder.pass(itemstack); + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItemDispenseBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItemDispenseBehaviour.java new file mode 100644 index 0000000000..edad373466 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/GTBoatItemDispenseBehaviour.java @@ -0,0 +1,72 @@ +package com.gregtechceu.gtceu.common.item; + +import com.gregtechceu.gtceu.common.entity.GTBoat; +import com.gregtechceu.gtceu.common.entity.GTChestBoat; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockSource; +import net.minecraft.core.Direction; +import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.DispenserBlock; + +public class GTBoatItemDispenseBehaviour extends DefaultDispenseItemBehavior { + + private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior(); + private final GTBoat.BoatType type; + private final boolean isChestBoat; + + public GTBoatItemDispenseBehaviour(GTBoat.BoatType type) { + this(type, false); + } + + public GTBoatItemDispenseBehaviour(GTBoat.BoatType type, boolean isChestBoat) { + this.type = type; + this.isChestBoat = isChestBoat; + } + + public ItemStack execute(BlockSource source, ItemStack stack) { + Direction direction = (Direction) source.getBlockState().getValue(DispenserBlock.FACING); + Level level = source.getLevel(); + double d0 = 0.5625 + (double) EntityType.BOAT.getWidth() / 2.0; + double d1 = source.x() + (double) direction.getStepX() * d0; + double d2 = source.y() + (double) ((float) direction.getStepY() * 1.125F); + double d3 = source.z() + (double) direction.getStepZ() * d0; + BlockPos blockpos = source.getPos().relative(direction); + + Boat boat; + if (isChestBoat) { + boat = new GTChestBoat(level, d0, d1, d2); + ((GTChestBoat) boat).setBoatType(type); + } else { + boat = new GTBoat(level, d0, d1, d2); + ((GTBoat) boat).setBoatType(type); + } + + boat.setYRot(direction.toYRot()); + double d4; + if (((Boat) boat).canBoatInFluid(level.getFluidState(blockpos))) { + d4 = 1.0; + } else { + if (!level.getBlockState(blockpos).isAir() || + !((Boat) boat).canBoatInFluid(level.getFluidState(blockpos.below()))) { + return this.defaultDispenseItemBehavior.dispense(source, stack); + } + + d4 = 0.0; + } + + ((Boat) boat).setPos(d1, d2 + d4, d3); + level.addFreshEntity((Entity) boat); + stack.shrink(1); + return stack; + } + + protected void playSound(BlockSource source) { + source.getLevel().levelEvent(1000, source.getPos(), 0); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/WoodTypeEntry.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/WoodTypeEntry.java index 82e4334adf..ddab441154 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/WoodTypeEntry.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/WoodTypeEntry.java @@ -80,6 +80,14 @@ public final class WoodTypeEntry { public final Item chestBoat; @Nullable public final String chestBoatRecipeName; + @Nullable + public final Item sign; + @Nullable + public final String signRecipeName; + @Nullable + public final Item hangingSign; + @Nullable + public final String hangingSignRecipeName; public final Material material; public final boolean addLogOreDict; @@ -115,6 +123,8 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull @Nullable Item stairs, @Nullable String stairsRecipeName, boolean addStairsCraftingRecipe, @Nullable Item boat, @Nullable String boatRecipeName, @Nullable Item chestBoat, @Nullable String chestBoatRecipeName, + @Nullable Item sign, @Nullable String signRecipeName, + @Nullable Item hangingSign, @Nullable String hangingSignRecipeName, @Nullable Material material, boolean addLogOreDict, boolean addPlanksOreDict, boolean addDoorsOreDict, boolean addSlabsOreDict, @@ -153,6 +163,10 @@ private WoodTypeEntry(@NotNull String modid, @NotNull String woodName, @NotNull this.boatRecipeName = boatRecipeName; this.chestBoat = chestBoat; this.chestBoatRecipeName = chestBoatRecipeName; + this.sign = sign; + this.signRecipeName = signRecipeName; + this.hangingSign = hangingSign; + this.hangingSignRecipeName = hangingSignRecipeName; this.material = material != null ? material : GTMaterials.Wood; this.addLogOreDict = addLogOreDict; @@ -219,6 +233,10 @@ public static class Builder { private String boatRecipeName; private Item chestBoat = null; private String chestBoatRecipeName; + private Item sign = null; + private String signRecipeName; + private Item hangingSign = null; + private String hangingSignRecipeName; @Nullable private Material material = null; @@ -462,6 +480,32 @@ public Builder chestBoat(@NotNull Item chestBoat, @Nullable String chestBoatReci return this; } + /** + * Add an entry for a sign + * + * @param sign the sign to add + * @param signRecipeName the recipe name for crafting the sign + * @return this + */ + public Builder sign(@NotNull Item sign, @Nullable String signRecipeName) { + this.sign = sign; + this.signRecipeName = signRecipeName; + return this; + } + + /** + * Add an entry for a sign + * + * @param hangingSign the hanging sign to add + * @param hangingSignRecipeName the recipe name for crafting the hanging sign + * @return this + */ + public Builder hangingSign(@NotNull Item hangingSign, @Nullable String hangingSignRecipeName) { + this.hangingSign = hangingSign; + this.hangingSignRecipeName = hangingSignRecipeName; + return this; + } + /** * Specify material for wood entry. If not provided, {@link GTMaterials#Wood} will be used * @@ -573,6 +617,7 @@ public WoodTypeEntry build() { fence, fenceRecipeName, fenceGate, fenceGateRecipeName, stairs, stairsRecipeName, addStairsCraftingRecipe, boat, boatRecipeName, chestBoat, chestBoatRecipeName, + sign, signRecipeName, hangingSign, hangingSignRecipeName, material, addLogOreDict, addPlanksOreDict, addDoorsOreDict, addSlabsOreDict, addFencesOreDict, addFenceGatesOreDict, addStairsOreDict, addPlanksUnificationInfo, diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java index d5421a05ea..6674b5b159 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java @@ -8,6 +8,7 @@ import com.gregtechceu.gtceu.api.data.chemical.material.stack.UnificationEntry; import com.gregtechceu.gtceu.api.data.tag.TagUtil; import com.gregtechceu.gtceu.common.data.GTBlocks; +import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.common.data.GTMaterials; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper; @@ -65,6 +66,8 @@ private static List getDefaultEntries() { .stairs(Items.OAK_STAIRS, "oak_stairs") .boat(Items.OAK_BOAT, "oak_boat") .chestBoat(Items.OAK_CHEST_BOAT, "oak_chest_boat") + .sign(Items.OAK_SIGN, "oak_sign") + .hangingSign(Items.OAK_HANGING_SIGN, "oak_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "spruce") @@ -81,6 +84,8 @@ private static List getDefaultEntries() { .stairs(Items.SPRUCE_STAIRS, "spruce_stairs") .boat(Items.SPRUCE_BOAT, "spruce_boat") .chestBoat(Items.SPRUCE_CHEST_BOAT, "spruce_chest_boat") + .sign(Items.SPRUCE_SIGN, "spruce_sign") + .hangingSign(Items.SPRUCE_HANGING_SIGN, "spruce_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "birch") @@ -97,6 +102,8 @@ private static List getDefaultEntries() { .stairs(Items.BIRCH_STAIRS, "birch_stairs") .boat(Items.BIRCH_BOAT, "birch_boat") .chestBoat(Items.BIRCH_CHEST_BOAT, "birch_chest_boat") + .sign(Items.BIRCH_SIGN, "birch_sign") + .hangingSign(Items.BIRCH_HANGING_SIGN, "birch_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "jungle") @@ -113,6 +120,8 @@ private static List getDefaultEntries() { .stairs(Items.JUNGLE_STAIRS, "jungle_stairs") .boat(Items.JUNGLE_BOAT, "jungle_boat") .chestBoat(Items.JUNGLE_CHEST_BOAT, "jungle_chest_boat") + .sign(Items.JUNGLE_SIGN, "jungle_sign") + .hangingSign(Items.JUNGLE_HANGING_SIGN, "jungle_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "acacia") @@ -129,6 +138,8 @@ private static List getDefaultEntries() { .stairs(Items.ACACIA_STAIRS, "acacia_stairs") .boat(Items.ACACIA_BOAT, "acacia_boat") .chestBoat(Items.ACACIA_CHEST_BOAT, "acacia_chest_boat") + .sign(Items.ACACIA_SIGN, "acacia_sign") + .hangingSign(Items.ACACIA_HANGING_SIGN, "acacia_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "dark_oak") @@ -145,6 +156,8 @@ private static List getDefaultEntries() { .stairs(Items.DARK_OAK_STAIRS, "dark_oak_stairs") .boat(Items.DARK_OAK_BOAT, "dark_oak_boat") .chestBoat(Items.DARK_OAK_CHEST_BOAT, "dark_oak_chest_boat") + .sign(Items.DARK_OAK_SIGN, "dark_oak_sign") + .hangingSign(Items.DARK_OAK_HANGING_SIGN, "dark_oak_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "bamboo") @@ -160,6 +173,8 @@ private static List getDefaultEntries() { .stairs(Items.BAMBOO_STAIRS, "bamboo_stairs") .boat(Items.BAMBOO_RAFT, "bamboo_raft") .chestBoat(Items.BAMBOO_CHEST_RAFT, "bamboo_chest_raft") + .sign(Items.BAMBOO_SIGN, "bamboo_sign") + .hangingSign(Items.BAMBOO_HANGING_SIGN, "bamboo_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "cherry") @@ -176,6 +191,8 @@ private static List getDefaultEntries() { .stairs(Items.CHERRY_STAIRS, "cherry_stairs") .boat(Items.CHERRY_BOAT, "cherry_boat") .chestBoat(Items.CHERRY_CHEST_BOAT, "cherry_chest_boat") + .sign(Items.CHERRY_SIGN, "cherry_sign") + .hangingSign(Items.CHERRY_HANGING_SIGN, "cherry_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "mangrove") @@ -192,6 +209,8 @@ private static List getDefaultEntries() { .stairs(Items.MANGROVE_STAIRS, "mangrove_stairs") .boat(Items.MANGROVE_BOAT, "mangrove_boat") .chestBoat(Items.MANGROVE_CHEST_BOAT, "mangrove_chest_boat") + .sign(Items.MANGROVE_SIGN, "mangrove_sign") + .hangingSign(Items.MANGROVE_HANGING_SIGN, "mangrove_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "crimson") @@ -207,6 +226,8 @@ private static List getDefaultEntries() { .fence(Items.CRIMSON_FENCE, "crimson_fence") .fenceGate(Items.CRIMSON_FENCE_GATE, "crimson_fence_gate") .stairs(Items.CRIMSON_STAIRS, "crimson_stairs") + .sign(Items.CRIMSON_SIGN, "crimson_sign") + .hangingSign(Items.CRIMSON_HANGING_SIGN, "crimson_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(mcModId, "warped") @@ -222,6 +243,8 @@ private static List getDefaultEntries() { .fence(Items.WARPED_FENCE, "warped_fence") .fenceGate(Items.WARPED_FENCE_GATE, "warped_fence_gate") .stairs(Items.WARPED_STAIRS, "warped_stairs") + .sign(Items.WARPED_SIGN, "warped_sign") + .hangingSign(Items.WARPED_HANGING_SIGN, "warped_hanging_sign") .registerAllUnificationInfo() .build(), new WoodTypeEntry.Builder(GTCEu.MOD_ID, "rubber") @@ -231,12 +254,15 @@ private static List getDefaultEntries() { .wood(GTBlocks.RUBBER_WOOD.asItem()) .strippedWood(GTBlocks.STRIPPED_RUBBER_WOOD.asItem()) .door(GTBlocks.RUBBER_DOOR.asItem(), null) - .trapdoor(GTBlocks.RUBBER_TRAPDOOR.asItem(), null) + .trapdoor(GTBlocks.RUBBER_TRAPDOOR.asItem(), "rubber_trapdoor") .slab(GTBlocks.RUBBER_SLAB.asItem(), null).addSlabRecipe() .fence(GTBlocks.RUBBER_FENCE.asItem(), null) .fenceGate(GTBlocks.RUBBER_FENCE_GATE.asItem(), null) .stairs(GTBlocks.RUBBER_STAIRS.asItem(), null).addStairsRecipe() - // .boat(GTItems.RUBBER_BOAT.asItem(), null) // TODO someone forgot boat textures. + .boat(GTItems.RUBBER_BOAT.asItem(), null) + .chestBoat(GTItems.RUBBER_CHEST_BOAT.asItem(), null) + .sign(GTBlocks.RUBBER_SIGN.asItem(), null) + .hangingSign(GTBlocks.RUBBER_HANGING_SIGN.asItem(), null) .generateLogToPlankRecipe(false) // rubber log does not have a tag .registerAllTags() .registerAllUnificationInfo() @@ -249,10 +275,12 @@ private static List getDefaultEntries() { .fence(GTBlocks.TREATED_WOOD_FENCE.asItem(), null) .fenceGate(GTBlocks.TREATED_WOOD_FENCE_GATE.asItem(), null) .stairs(GTBlocks.TREATED_WOOD_STAIRS.asItem(), null).addStairsRecipe() - // .boat(GTItems.TREATED_WOOD_BOAT.asItem(), null) // TODO someone forgot boat textures. + .boat(GTItems.TREATED_WOOD_BOAT.asItem(), null) + .chestBoat(GTItems.TREATED_WOOD_CHEST_BOAT.asItem(), null) + .sign(GTBlocks.TREATED_WOOD_SIGN.asItem(), null) + .hangingSign(GTBlocks.TREATED_WOOD_HANGING_SIGN.asItem(), null) .material(TreatedWood) - .generateLogToPlankRecipe(false) - .registerAllUnificationInfo() + .registerUnificationInfo(false, true, true, true, true, true, true, true) .build()); } return DEFAULT_ENTRIES; @@ -458,6 +486,102 @@ public static void registerWoodTypeRecipe(Consumer provider, @No } } + // sign + if (entry.sign != null && entry.slab != null) { + final boolean hasSignRecipe = entry.signRecipeName != null; + String recipeName = hasSignRecipe ? entry.signRecipeName : name + "_sign"; + if (ConfigHolder.INSTANCE.recipes.hardWoodRecipes) { + VanillaRecipeHelper.addShapedRecipe(provider, recipeName + "_iron", new ItemStack(entry.sign), + "LLL", "rPr", "sSd", + 'P', entry.planks, + 'r', new UnificationEntry(screw, Iron), + 'L', entry.slab, + 'S', entry.getStick()); + + // plank -> sign assembling + ASSEMBLER_RECIPES.recipeBuilder(recipeName + "_iron") + .circuitMeta(4) + .inputItems(new ItemStack(entry.slab, 1)) + .inputItems(entry.getStick(), 1) + .inputFluids(Iron.getFluid(GTValues.L / 9)) + .outputItems(entry.sign, 3) + .duration(200).EUt(4).save(provider); + + VanillaRecipeHelper.addShapedRecipe(provider, recipeName + "_steel", new ItemStack(entry.sign, 2), + "LLL", "rPr", "sSd", + 'P', entry.planks, + 'r', new UnificationEntry(screw, Steel), + 'L', entry.slab, + 'S', entry.getStick()); + + // plank -> sign assembling + ASSEMBLER_RECIPES.recipeBuilder(recipeName + "_steel") + .circuitMeta(4) + .inputItems(new ItemStack(entry.slab, 1)) + .inputItems(entry.getStick(), 1) + .inputFluids(Steel.getFluid(GTValues.L / 9)) + .outputItems(entry.sign, 5) + .duration(200).EUt(4).save(provider); + } else { + VanillaRecipeHelper.addShapedRecipe(provider, recipeName, new ItemStack(entry.sign, 3), + "PPP", "PPP", " s ", + 'P', entry.planks, + 's', entry.getStick()); + } + + if (entry.hangingSign != null) { + final boolean hasHangingSignRecipe = entry.hangingSignRecipeName != null; + String recipeNameHanging = hasHangingSignRecipe ? entry.hangingSignRecipeName : name + "_hanging_sign"; + ASSEMBLER_RECIPES.recipeBuilder(recipeNameHanging) + .inputItems(entry.sign) + .inputItems(ring, Iron, 2) + .inputItems(Items.CHAIN, 2) + .circuitMeta(5) + .duration(150) + .EUt(4) + .save(provider); + } + } + + // trapdoor + if (entry.trapdoor != null) { + final boolean hasTrapdoorRecipe = entry.trapdoorRecipeName != null; + String recipeName = hasTrapdoorRecipe ? entry.trapdoorRecipeName : name + "_trapdoor"; + if (ConfigHolder.INSTANCE.recipes.hardWoodRecipes) { + VanillaRecipeHelper.addShapedRecipe(provider, recipeName + "_iron", new ItemStack(entry.trapdoor), + "bPS", "PdP", "SPb", + 'P', entry.planks, + 'b', new UnificationEntry(bolt, Iron), + 'S', entry.getStick()); + + // plank -> trapdoor assembling + ASSEMBLER_RECIPES.recipeBuilder(recipeName + "_iron") + .circuitMeta(3) + .inputItems(new ItemStack(entry.planks, 2)) + .inputFluids(Iron.getFluid(GTValues.L / 9)) + .outputItems(entry.trapdoor) + .duration(200).EUt(4).save(provider); + + VanillaRecipeHelper.addShapedRecipe(provider, recipeName + "_steel", new ItemStack(entry.trapdoor, 2), + "bPS", "PdP", "SPb", + 'P', entry.planks, + 'b', new UnificationEntry(bolt, Steel), + 'S', entry.getStick()); + + // plank -> trapdoor assembling + ASSEMBLER_RECIPES.recipeBuilder(recipeName + "_steel") + .circuitMeta(3) + .inputItems(new ItemStack(entry.planks, 2)) + .inputFluids(Steel.getFluid(GTValues.L / 9)) + .outputItems(entry.trapdoor, 2) + .duration(200).EUt(4).save(provider); + } else { + VanillaRecipeHelper.addShapedRecipe(provider, recipeName, new ItemStack(entry.trapdoor, 2), + "PPP", "PPP", + 'P', entry.planks); + } + } + // stairs if (entry.stairs != null) { final boolean hasStairRecipe = entry.stairsRecipeName != null; @@ -592,29 +716,24 @@ public static void registerWoodTypeRecipe(Consumer provider, @No // chest boat if (entry.chestBoat != null) { final boolean hasChestBoatRecipe = entry.chestBoatRecipeName != null; + String recipeName = hasChestBoatRecipe ? entry.chestBoatRecipeName : name + "_chest_boat"; if (ConfigHolder.INSTANCE.recipes.hardWoodRecipes) { - if (entry.boat != null) { - - VanillaRecipeHelper.addShapedRecipe(provider, - hasChestBoatRecipe ? entry.chestBoatRecipeName : name + "_chest_boat", - new ItemStack(entry.chestBoat), - " B ", "SCS", " w ", - 'B', entry.boat, - 'S', new UnificationEntry(bolt, Wood), - 'C', Tags.Items.CHESTS_WOODEN); - } + VanillaRecipeHelper.addShapedRecipe(provider, recipeName, + new ItemStack(entry.chestBoat), + " B ", "SCS", " w ", + 'B', entry.boat, + 'S', new UnificationEntry(bolt, Wood), + 'C', Tags.Items.CHESTS_WOODEN); } else { - if (!hasChestBoatRecipe) { - VanillaRecipeHelper.addShapelessRecipe(provider, name + "_chest_boat", - new ItemStack(entry.chestBoat), - entry.boat, Tags.Items.CHESTS); - } + VanillaRecipeHelper.addShapelessRecipe(provider, recipeName, + new ItemStack(entry.chestBoat), + entry.boat, Tags.Items.CHESTS_WOODEN); } - // plank -> boat assembling + // boat -> chest boat assembling ASSEMBLER_RECIPES.recipeBuilder(name + "_chest_boat") .inputItems(new ItemStack(entry.boat)) - .inputItems(Tags.Items.CHESTS) + .inputItems(Tags.Items.CHESTS_WOODEN) .outputItems(entry.chestBoat) .circuitMeta(16) .duration(100).EUt(4).save(provider); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 6131827e9f..e416b85be7 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -20,6 +20,8 @@ public net.minecraft.world.entity.item.ItemEntity f_31986_ # pickupDelay public net.minecraft.server.network.ServerGamePacketListenerImpl f_9737_ # aboveGroundTickCount public net.minecraft.world.entity.Entity m_20115_(IZ)V # setSharedFlag +public net.minecraft.world.entity.vehicle.Boat f_38285_ # DATA_ID_TYPE + # for AE2 to be able to load (idk why but it needs these?) public net.minecraft.world.level.block.Blocks m_50774_(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z # always public net.minecraft.world.level.block.Blocks m_50805_(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z # never diff --git a/src/main/resources/assets/gtceu/textures/entity/boat/rubber_boat.png b/src/main/resources/assets/gtceu/textures/entity/boat/rubber_boat.png new file mode 100644 index 0000000000000000000000000000000000000000..97e9a65ef9b698e1e31ddb87af050cd72e5a666e GIT binary patch literal 2872 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/entity/boat/treated_chest_boat.png b/src/main/resources/assets/gtceu/textures/entity/boat/treated_chest_boat.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a00cba8f4ee1cb9de440006eee3b68de0d6d3f GIT binary patch literal 4714 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 a8a`wi?vi0G@9Ogipr>W1*`V?4)qeo+sTg$t literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gtceu/textures/item/rubber_boat.png b/src/main/resources/assets/gtceu/textures/item/rubber_boat.png new file mode 100644 index 0000000000000000000000000000000000000000..d2998da345c49c0abc68e24c460d8f962e29e16c GIT binary patch literal 614 zcmV-s0-61ZP)Llg(=rQ5400FEcfhnY1%bhz+Ln!w+mD7|?*$MafR; zvf$FSf0JvMf;$Cwv$8Hqp^GLIv9ZNMLYZkM&15n(ljma0q@l|`c-(g%@0@cv_gx{S zthUT>ze~Y5>@J68Bmm{V+mNG9r%0>>svJUsfLxU5&`jsj?qNIE^R; zItT7d={uWc_FB*nBRLUQC%~&wd;@5k1_1e7Ho0$fsaGtVMwF7O{qUxuZ5nufz`IwA zeE!+N%uk*tM4lgD6r(HN|`+Ruw zAT76C%(7gvSuWXp**!~13WmUGbO|ncs7lg6vAT3m)~f|Z z*(_i4pv!_5i?PtB{{Y~;7xDU`mFC-3i`rT)t)yJc;tht>D;B+>BJbv7#EZ%brzaix z{_REzEG{Hw9ku<`+?~xb-e8CuND79))-{|)myD2trA1SG`qrH3`2>92kpve#zU-c1 z>ly_^;0DwA$&BJLe>;9k;tdja-9YlyY0+%{LDw~5WQJlw^0=7e*Lj$jxUo{AdD5n6 zXcTM%*PGJM&uilHa+s0)+jEP)LG#9%OS*Te2WSjJb4Do(o%Kq#aL*YyI3@Wm_HI;lQ|aCDF}yGqIN7>&n+{M84INJvm?w0a=Q!oAx7 ztZ$j!zM_MHyPvOQ>$F_SKz{_+^@7UBIJ2u1D-}wP$J%C%wapqO z$76lV#4?IxZua*KQK>ar0PL3|0R-U1n-)*9!$EbqIXw`WmW}7uI{?$NdA2lz)BG7g z{C3vg?U75z(PBe<{2uCYuG`HH0AROdv6ShBsEW<BKt1~w-!B{H6#`X~-$p~h> z1F1Gc^2&gVc#t0F$6;AMeKZ|_l7pQJc1soj`OgNAAC6$wn;5o4j|vi+N`9w;BBWq+ z__BEUw$L*qU%XeA*e6vswvR|?Dtc64*xeOT&RmaT*$NLlRa<_M8H8yXe~CO_>hDBcT(Ir|IBnVhn5Ln&K)nqkft%YwMI`|5{a0AtTFqxt0L+3l?S>sW6rL|JXTkcP!m%$oJFfEn%MHbBm zO}D^Be?d8C=vM*WeY&RIu=#NtI^2O^v5d8F<=yf2Wlh^XtfZ(r7Inwsyf@JhH!J84 zrfdK+@kfo*yTCVWs3O6fotTf%hl!Q=%s)_i}o9uNS ziNAV^4RGF@;8*tSYx&=Odn{qi^MnQ=@FbCDyI_-~w uu$^3NoVK~?|31n7I!J*DD!#=-$N4vqoX0pCw-fsS0000`p#+r~IOw>VTWT}p_ zl4zV5{R14_9Y_pu=;}y9NQ{evOW6nsxHOW6QjgNYwe)A&>+5j6YtICIk~jCf?|aYZ zd7kgx1Gm`fN>Z+_B;{@QwyC3=hfzOMbMq2leW^P*P0D;OCr01XZ%oH`F6?aUOIJP2yt;Y9K_fQA6+cxvOc8|0V0^`uvPqtK)(w ziK%e_cJ{A^eFZ{JcH7@bHJO^5Cp6*3H2aP=if>Gn)k=Z2)Z z>QR_(yXZjdc0PP7l3vs>uG{Q>KX+wrGzS#`9O_k`#@vtxi2$!(B*!o6uP zrKSZj+8%i)Xd-5Ug5Py1-=u~j&4#QB4)rPk`$r8nQxQtdHhNtW4+^4wAA83Jijabs ziujzZxJ0spf9jGRkjYkv`hCQM0=+&Q5i#w9%QnPRxac8YE(KVQhxwW_IQZ4Hg%Tm4 z4svr)=~1ag{;~s;BV!V@9@1XpxNXJ@D#+0#r2Oy1{?q;dq4e|MoILkd00000NkvXX Hu0mjfpphNC literal 0 HcmV?d00001