From 07ca259c442c7284d7d653e3b38557ad06d52217 Mon Sep 17 00:00:00 2001 From: TheClashFruit Date: Tue, 27 Aug 2024 21:22:02 +0200 Subject: [PATCH 1/4] feat: implement the mechanical toilet mostly and it's other stuff --- .../blocks/toilet/MechanicalToiletBlock.java | 103 +++ .../toilet/MechanicalToiletBlockEntity.java | 96 +++ .../pissnshit/registry/Blocks.java | 43 ++ .../pissnshit/registry/ItemGroups.java | 7 +- .../pissnshit/registry/Items.java | 17 + .../blockstates/mechanical_toilet.json | 19 + .../assets/pissnshit/lang/en_us.json | 10 +- .../models/block/mechanical_toilet.json | 687 +++++++++--------- .../assets/pissnshit/models/item/flushed.json | 6 + .../models/item/mechanical_toilet.json | 3 + .../pissnshit/textures/item/flushed.png | Bin 0 -> 761 bytes .../advancements/pissnshit/flushed.json | 31 + .../pissnshit/mechanical_marvel.json | 31 + .../pissnshit/recipes/mechanical_toilet.json | 29 + 14 files changed, 752 insertions(+), 330 deletions(-) create mode 100644 src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java create mode 100644 src/main/resources/assets/pissnshit/blockstates/mechanical_toilet.json create mode 100644 src/main/resources/assets/pissnshit/models/item/flushed.json create mode 100644 src/main/resources/assets/pissnshit/models/item/mechanical_toilet.json create mode 100644 src/main/resources/assets/pissnshit/textures/item/flushed.png create mode 100644 src/main/resources/data/minecraft/advancements/pissnshit/flushed.json create mode 100644 src/main/resources/data/minecraft/advancements/pissnshit/mechanical_marvel.json create mode 100644 src/main/resources/data/pissnshit/recipes/mechanical_toilet.json diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java new file mode 100644 index 0000000..8cee95a --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java @@ -0,0 +1,103 @@ +package me.theclashfruit.pissnshit.blocks.toilet; + +import com.simibubi.create.content.equipment.wrench.IWrenchable; +import com.simibubi.create.foundation.block.IBE; +import me.theclashfruit.pissnshit.registry.Blocks; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.HorizontalFacingBlock; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.Properties; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.WorldView; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; + +import static net.minecraft.state.property.Properties.HORIZONTAL_FACING; + +public class MechanicalToiletBlock extends HorizontalFacingBlock implements IBE, IWrenchable { + public MechanicalToiletBlock(Settings properties) { + super(properties); + + setDefaultState(getDefaultState().with(HORIZONTAL_FACING, Direction.NORTH)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(HORIZONTAL_FACING); + } + + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(Properties.HORIZONTAL_FACING, ctx.getHorizontalPlayerFacing().getOpposite()); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext ctx) { + Direction dir = state.get(FACING); + VoxelShape shape = VoxelShapes.empty(); + + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.1875, 0, 0.125, 0.8125, 0.125, 1), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.125, 0.125, 0.0625, 0.875, 0.25, 0.75), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.0625, 0.5, 0, 0.9375, 0.625, 0.125), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.0625, 0.5, 0.6875, 0.9375, 0.625, 0.8125), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.0625, 0.5, 0.125, 0.1875, 0.625, 0.6875), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.8125, 0.5, 0.125, 0.9375, 0.625, 0.6875), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.125, 0.125, 0.75, 0.875, 0.5, 0.984375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.125, 0.5, 0.859375, 0.875, 1.1875, 0.984375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.109375, 1.15625, 0.84375, 0.890625, 1.25, 1), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.15625, 0.625, 0.765625, 0.859375, 1.375, 0.828125), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.125, 0.25, 0.0625, 0.25, 0.5, 0.75), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.75, 0.25, 0.0625, 0.875, 0.5, 0.75), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.25, 0.25, 0.0625, 0.75, 0.5, 0.1875), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.25, 0.25, 0.625, 0.75, 0.5, 0.75), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.25, 0.25, 0.4375, 0.75, 0.3125, 0.625), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.25, 0.25, 0.1875, 0.375, 0.3125, 0.4375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.625, 0.25, 0.1875, 0.75, 0.3125, 0.4375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.375, 0.25, 0.1875, 0.4375, 0.328125, 0.4375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.4375, 0.25, 0.375, 0.5625, 0.328125, 0.4375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.5625, 0.25, 0.1875, 0.625, 0.328125, 0.4375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.0625, 0.921875, 0.9375, 0.125, 1.046875, 0.96875), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.421875, 0.25, 0.171875, 0.578125, 0.296875, 0.375), BooleanBiFunction.OR); + shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(0.1875, 0.1875, 0.875, 0.8125, 0.8125, 1), BooleanBiFunction.OR); + + return rotateShape(Direction.NORTH, dir, shape); + } + + @Override + public BlockState updateAfterWrenched(BlockState newState, ItemUsageContext context) { + return newState; + } + + @Override + public Class getBlockEntityClass() { + return MechanicalToiletBlockEntity.class; + } + + @Override + public BlockEntityType getBlockEntityType() { + return Blocks.MECHANICAL_TOILET_BLOCK_ENTITY; + } + + public static VoxelShape rotateShape(Direction from, Direction to, VoxelShape shape) { + VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; + + int times = (to.getHorizontal() - from.getHorizontal() + 4) % 4; + + for (int i = 0; i < times; i++) { + buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combine(buffer[1], VoxelShapes.cuboid(1-maxZ, minY, minX, 1-minZ, maxY, maxX), BooleanBiFunction.OR)); + + buffer[0] = buffer[1]; + buffer[1] = VoxelShapes.empty(); + } + + return buffer[0]; + } +} diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java new file mode 100644 index 0000000..7463c66 --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java @@ -0,0 +1,96 @@ +package me.theclashfruit.pissnshit.blocks.toilet; + +import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.fluid.CombinedTankWrapper; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.LangBuilder; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.infrastructure.config.AllConfigs; +import io.github.fabricators_of_create.porting_lib.fluids.FluidStack; +import io.github.fabricators_of_create.porting_lib.util.FluidTextUtil; +import io.github.fabricators_of_create.porting_lib.util.FluidUnit; +import me.theclashfruit.pissnshit.registry.Blocks; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.Storage; +import net.fabricmc.fabric.api.transfer.v1.storage.base.SidedStorageBlockEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.text.Text; +import net.minecraft.text.TextColor; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; + +import javax.annotation.Nullable; +import java.awt.*; +import java.util.List; + +public class MechanicalToiletBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation, SidedStorageBlockEntity { + private SmartFluidTankBehaviour tank; + + public MechanicalToiletBlockEntity(BlockPos pos, BlockState state) { + super(Blocks.MECHANICAL_TOILET_BLOCK_ENTITY, pos, state); + } + + @Override + public void addBehaviours(List behaviours) { + tank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, FluidConstants.BUCKET, true) + .forbidInsertion(); + + behaviours.add(tank); + } + + @Nullable + @Override + public Storage getFluidStorage(@Nullable Direction face) { + return tank.getCapability(); + } + + @Override + public void tick() { + super.tick(); + + if (world.isClient) return; + } + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + Lang.translate("gui.goggles.basin_contents") + .forGoggles(tooltip); + + boolean isEmpty = true; + + FluidUnit unit = AllConfigs.client().fluidUnitType.get(); + LangBuilder unitSuffix = Lang.translate(unit.getTranslationKey()); + boolean simplify = AllConfigs.client().simplifyFluidUnit.get(); + + for (SmartFluidTankBehaviour.TankSegment tank : tank.getTanks()) { + FluidStack fluidStack = tank.getTank().getFluid(); + + if (fluidStack.isEmpty()) + continue; + + Lang.text("") + .add(Lang.fluidName(fluidStack) + .add(Lang.text(" ")) + .style(Formatting.GRAY) + .add(Lang.text(FluidTextUtil.getUnicodeMillibuckets(fluidStack.getAmount(), unit, simplify)) + .add(unitSuffix) + .style(Formatting.BLUE))) + .forGoggles(tooltip, 1); + + isEmpty = false; + } + + if (isEmpty) + tooltip.remove(0); + + return true; + } +} diff --git a/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java b/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java index 584152f..01c1b66 100644 --- a/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java +++ b/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java @@ -1,14 +1,27 @@ package me.theclashfruit.pissnshit.registry; +import com.simibubi.create.content.kinetics.BlockStressDefaults; +import com.simibubi.create.foundation.data.AssetLookup; +import com.simibubi.create.foundation.data.BlockStateGen; +import com.simibubi.create.foundation.data.CreateRegistrate; +import com.simibubi.create.foundation.data.SharedProperties; +import com.tterrag.registrate.util.entry.BlockEntityEntry; +import com.tterrag.registrate.util.entry.BlockEntry; +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletBlock; +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletBlockEntity; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.client.render.RenderLayer; import net.minecraft.fluid.FlowableFluid; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.util.Identifier; +import static com.simibubi.create.foundation.data.ModelGen.customItemModel; +import static com.simibubi.create.foundation.data.TagGen.axeOrPickaxe; import static me.theclashfruit.pissnshit.PissAndShit.MOD_ID; import static me.theclashfruit.pissnshit.registry.Fluids.STILL_PISS; @@ -25,5 +38,35 @@ public class Blocks { .luminance(CandleBlock.STATE_TO_LUMINANCE) .pistonBehavior(PistonBehavior.DESTROY))); + public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(MOD_ID); + + public static final MechanicalToiletBlock MECHANICAL_TOILET = Registry.register(Registries.BLOCK, new Identifier(MOD_ID, "mechanical_toilet"), new MechanicalToiletBlock(AbstractBlock.Settings.create() + .mapColor(MapColor.ORANGE) + )); + + public static final BlockEntityType MECHANICAL_TOILET_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier(MOD_ID, "mechanical_toilet_block_entity"), BlockEntityType.Builder.create(MechanicalToiletBlockEntity::new, MECHANICAL_TOILET).build(null)); + + /* + REGISTRATE + .block("encased_fan", MechanicalToiletBlock::new) + .initialProperties(SharedProperties::copperMetal) + .properties(p -> p.mapColor(MapColor.ORANGE)) + .blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p))) + .transform(BlockStressDefaults.setImpact(8.0)) + .item() + .transform(customItemModel()) + .addLayer(() -> RenderLayer::getCutout) + .register(); + */ + + /* + public static final BlockEntityEntry MECHANICAL_TOILET_ENTITY = REGISTRATE + .blockEntity("encased_fan", MechanicalToiletBlockEntity::new) + .instance(() -> MechanicalToiletCogInstance::new) + .validBlocks(MECHANICAL_TOILET) + .renderer(() -> MechanicalToiletRenderer::new) + .register(); + */ + public static void init() {} } diff --git a/src/main/java/me/theclashfruit/pissnshit/registry/ItemGroups.java b/src/main/java/me/theclashfruit/pissnshit/registry/ItemGroups.java index 468aa57..3f60459 100644 --- a/src/main/java/me/theclashfruit/pissnshit/registry/ItemGroups.java +++ b/src/main/java/me/theclashfruit/pissnshit/registry/ItemGroups.java @@ -23,8 +23,13 @@ public class ItemGroups { entries.add(Items.SHIT); entries.add(Items.HOLY_SHIT); + // 😳 + entries.add(Items.FLUSHED); + entries.add(Items.SHIT_CANDLE); - entries.add(Blocks.SHIT_BLOCK); + entries.add(Items.SHIT_BLOCK); + + entries.add(Items.MECHANICAL_TOILET); }) .build(); diff --git a/src/main/java/me/theclashfruit/pissnshit/registry/Items.java b/src/main/java/me/theclashfruit/pissnshit/registry/Items.java index d32dfe6..40aebf7 100644 --- a/src/main/java/me/theclashfruit/pissnshit/registry/Items.java +++ b/src/main/java/me/theclashfruit/pissnshit/registry/Items.java @@ -76,6 +76,15 @@ public class Items { ) ); + public static Item FLUSHED = register( + "flushed", + new Item( + new Item + .Settings() + .rarity(Rarity.EPIC) + ) + ); + public static Item SHIT_BLOCK = register( "shit_block", new BlockItem( @@ -91,6 +100,14 @@ public class Items { ) ); + public static Item MECHANICAL_TOILET = register( + "mechanical_toilet", + new BlockItem( + Blocks.MECHANICAL_TOILET, + new Item.Settings() + ) + ); + public static void init() {} private static Item register(String id, Item item) { diff --git a/src/main/resources/assets/pissnshit/blockstates/mechanical_toilet.json b/src/main/resources/assets/pissnshit/blockstates/mechanical_toilet.json new file mode 100644 index 0000000..1bb3a08 --- /dev/null +++ b/src/main/resources/assets/pissnshit/blockstates/mechanical_toilet.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "pissnshit:block/mechanical_toilet" + }, + "facing=west": { + "model": "pissnshit:block/mechanical_toilet", + "y": 270 + }, + "facing=east": { + "model": "pissnshit:block/mechanical_toilet", + "y": 90 + }, + "facing=south": { + "model": "pissnshit:block/mechanical_toilet", + "y": 180 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/pissnshit/lang/en_us.json b/src/main/resources/assets/pissnshit/lang/en_us.json index 6c828ee..6c9df84 100644 --- a/src/main/resources/assets/pissnshit/lang/en_us.json +++ b/src/main/resources/assets/pissnshit/lang/en_us.json @@ -5,13 +5,15 @@ "item.pissnshit.shit": "Shit", "item.pissnshit.holy_shit": "Holy Shit", + "item.pissnshit.flushed": "Flushed", + "block.pissnshit.piss": "Piss", "block.pissnshit.shit_block": "Shit Block", "block.pissnshit.shit_candle": "Shit Candle", "block.pissnshit.shit_candle.tooltip": "§8§oIt smells like shit...", - "block.pissnshit.mechanical_sanctifier": "Mechanical Sanctifier", + "block.pissnshit.mechanical_toilet": "Mechanical Toilet", "effect.pissnshit.diarrhea": "Diarrhea", @@ -38,6 +40,12 @@ "advancements.pissnshit.piss_cubed.title": "Piss³", "advancements.pissnshit.piss_cubed.description": "Obtain a bucket of piss.", + "advancements.pissnshit.mechanical_marvel.title": "Mechanical Marvel", + "advancements.pissnshit.mechanical_marvel.description": "Craft a mechanical toilet.", + + "advancements.pissnshit.flushed.title": "Flush(ed)", + "advancements.pissnshit.flushed.description": "Use your newly operational mechanical toilet.", + "death.attack.fullOfPiss": "%1$s got full of piss.", "death.attack.fullOfShit": "%1$s got full of shit.", diff --git a/src/main/resources/assets/pissnshit/models/block/mechanical_toilet.json b/src/main/resources/assets/pissnshit/models/block/mechanical_toilet.json index e332ef6..c63436a 100644 --- a/src/main/resources/assets/pissnshit/models/block/mechanical_toilet.json +++ b/src/main/resources/assets/pissnshit/models/block/mechanical_toilet.json @@ -1,330 +1,361 @@ { - "credit": "Made with Blockbench", - "textures": { - "0": "minecraft:block/water_still", - "1": "create:block/pipes", - "missing": "minecraft:block/copper_block", - "particle": "minecraft:block/copper_block" - }, - "elements": [ - { - "from": [3, 0, 2], - "to": [13, 2, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [3, 0, 0]}, - "color": 5, - "faces": { - "north": {"uv": [0, 0, 10, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 10, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 10, 14], "texture": "#missing"}, - "down": {"uv": [0, 0, 10, 14], "texture": "#missing"} - } - }, - { - "from": [2, 2, 1], - "to": [14, 4, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [2, 2, 1]}, - "color": 3, - "faces": { - "north": {"uv": [0, 0, 12, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 11, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 12, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 11, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 12, 11], "texture": "#missing"}, - "down": {"uv": [0, 0, 12, 11], "texture": "#missing"} - } - }, - { - "from": [1, 8, 0], - "to": [15, 10, 2], - "rotation": {"angle": 0, "axis": "y", "origin": [1, 8, 0]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "down": {"uv": [0, 0, 14, 2], "texture": "#missing"} - } - }, - { - "from": [1, 8, 11], - "to": [15, 10, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [1, 8, 11]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 14, 2], "texture": "#missing"}, - "down": {"uv": [0, 0, 14, 2], "texture": "#missing"} - } - }, - { - "from": [1, 8, 2], - "to": [3, 10, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [3, 8, 0]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 9, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 9, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 9, 2], "rotation": 90, "texture": "#missing"}, - "down": {"uv": [0, 0, 9, 2], "rotation": 270, "texture": "#missing"} - } - }, - { - "from": [13, 8, 2], - "to": [15, 10, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [15, 8, 0]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 9, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 9, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 9, 2], "rotation": 90, "texture": "#missing"}, - "down": {"uv": [0, 0, 9, 2], "rotation": 270, "texture": "#missing"} - } - }, - { - "from": [2, 2, 12], - "to": [14, 8, 15.75], - "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 13]}, - "color": 1, - "faces": { - "north": {"uv": [0, 0, 12, 6], "texture": "#missing"}, - "east": {"uv": [0, 0, 3.75, 6], "texture": "#missing"}, - "south": {"uv": [0, 0, 12, 6], "texture": "#missing"}, - "west": {"uv": [0, 0, 3.75, 6], "texture": "#missing"}, - "up": {"uv": [0, 0, 12, 3.75], "texture": "#missing"}, - "down": {"uv": [0, 0, 12, 3.75], "texture": "#missing"} - } - }, - { - "from": [2, 8, 13.75], - "to": [14, 19, 15.75], - "rotation": {"angle": 0, "axis": "y", "origin": [2, 8, 14]}, - "faces": { - "north": {"uv": [2, 2, 14, 13], "texture": "#missing"}, - "east": {"uv": [0, 2, 2, 13], "texture": "#missing"}, - "south": {"uv": [2, 2, 14, 13], "texture": "#missing"}, - "west": {"uv": [14, 2, 16, 13], "texture": "#missing"}, - "up": {"uv": [2, 0, 14, 2], "texture": "#missing"}, - "down": {"uv": [2, 13, 14, 15], "texture": "#missing"} - } - }, - { - "from": [1.75, 18.5, 13.5], - "to": [14.25, 20, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [2, 18, 14]}, - "faces": { - "north": {"uv": [0, 0, 12.5, 1.5], "texture": "#missing"}, - "east": {"uv": [0, 0, 2.5, 1.5], "texture": "#missing"}, - "south": {"uv": [1.75, 0.5, 14.25, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 2.5, 1.5], "texture": "#missing"}, - "up": {"uv": [1.75, 7, 14.25, 9.5], "texture": "#missing"}, - "down": {"uv": [0, 0, 12.5, 2.5], "texture": "#missing"} - } - }, - { - "from": [2.5, 10, 12.25], - "to": [13.75, 22, 13.25], - "rotation": {"angle": 0, "axis": "x", "origin": [3, 10, 12.25]}, - "color": 5, - "faces": { - "north": {"uv": [0, 0, 11.25, 12], "texture": "#missing"}, - "east": {"uv": [0, 0, 1, 12], "texture": "#missing"}, - "south": {"uv": [0, 0, 11.25, 12], "texture": "#missing"}, - "west": {"uv": [0, 0, 1, 12], "texture": "#missing"}, - "up": {"uv": [0, 0, 11.25, 1], "texture": "#missing"}, - "down": {"uv": [0, 0, 11.25, 1], "texture": "#missing"} - } - }, - { - "from": [2, 4, 1], - "to": [4, 8, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [2, 6, 1]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "east": {"uv": [0, 0, 11, 4], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "west": {"uv": [0, 0, 11, 4], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 11], "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 11], "texture": "#missing"} - } - }, - { - "from": [12, 4, 1], - "to": [14, 8, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 1]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "east": {"uv": [0, 0, 11, 4], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "west": {"uv": [0, 0, 11, 4], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 11], "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 11], "texture": "#missing"} - } - }, - { - "from": [4, 4, 1], - "to": [12, 8, 3], - "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 1]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 8, 4], "texture": "#missing"}, - "east": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "south": {"uv": [0, 0, 8, 4], "texture": "#missing"}, - "west": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 8], "rotation": 90, "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 8], "rotation": 270, "texture": "#missing"} - } - }, - { - "from": [4, 4, 10], - "to": [12, 8, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 10]}, - "color": 4, - "faces": { - "north": {"uv": [0, 0, 8, 4], "texture": "#missing"}, - "east": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "south": {"uv": [0, 0, 8, 4], "texture": "#missing"}, - "west": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 8], "rotation": 90, "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 8], "rotation": 270, "texture": "#missing"} - } - }, - { - "from": [4, 4, 7], - "to": [12, 5, 10], - "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 8]}, - "color": 7, - "faces": { - "north": {"uv": [0, 0, 8, 1], "texture": "#missing"}, - "east": {"uv": [0, 0, 3, 1], "texture": "#missing"}, - "south": {"uv": [0, 0, 8, 1], "texture": "#missing"}, - "west": {"uv": [0, 0, 3, 1], "texture": "#missing"}, - "up": {"uv": [0, 0, 8, 3], "texture": "#missing"}, - "down": {"uv": [0, 0, 8, 3], "texture": "#missing"} - } - }, - { - "from": [4, 4, 3], - "to": [6, 5, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 5]}, - "color": 7, - "faces": { - "north": {"uv": [0, 0, 2, 1], "texture": "#missing"}, - "east": {"uv": [0, 0, 4, 1], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 1], "texture": "#missing"}, - "west": {"uv": [0, 0, 4, 1], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 4], "texture": "#missing"} - } - }, - { - "from": [10, 4, 3], - "to": [12, 5, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 5]}, - "color": 7, - "faces": { - "north": {"uv": [0, 0, 2, 1], "texture": "#missing"}, - "east": {"uv": [0, 0, 4, 1], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 1], "texture": "#missing"}, - "west": {"uv": [0, 0, 4, 1], "texture": "#missing"}, - "up": {"uv": [0, 0, 2, 4], "texture": "#missing"}, - "down": {"uv": [0, 0, 2, 4], "texture": "#missing"} - } - }, - { - "from": [6, 4, 3], - "to": [7, 5.25, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [6, 4, 5]}, - "color": 9, - "faces": { - "north": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "east": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, - "south": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "west": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, - "up": {"uv": [0, 0, 1, 4], "texture": "#missing"}, - "down": {"uv": [0, 0, 1, 4], "texture": "#missing"} - } - }, - { - "from": [7, 4, 6], - "to": [9, 5.25, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 6]}, - "color": 9, - "faces": { - "north": {"uv": [0, 0, 2, 1.25], "texture": "#missing"}, - "east": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "south": {"uv": [0, 0, 2, 1.25], "texture": "#missing"}, - "west": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "up": {"uv": [0, 0, 1, 2], "rotation": 90, "texture": "#missing"}, - "down": {"uv": [0, 0, 1, 2], "rotation": 270, "texture": "#missing"} - } - }, - { - "from": [9, 4, 3], - "to": [10, 5.25, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [6, 4, 5]}, - "color": 9, - "faces": { - "north": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "east": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, - "south": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, - "west": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, - "up": {"uv": [0, 0, 1, 4], "texture": "#missing"}, - "down": {"uv": [0, 0, 1, 4], "texture": "#missing"} - } - }, - { - "from": [1, 14.75, 15], - "to": [2, 16.75, 15.5], - "rotation": {"angle": -22.5, "axis": "x", "origin": [0, 14.75, 14.25]}, - "color": 6, - "faces": { - "north": {"uv": [0, 0, 1, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 0.5, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 1, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 0.5, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 1, 0.5], "texture": "#missing"}, - "down": {"uv": [0, 0, 1, 0.5], "texture": "#missing"} - } - }, - { - "name": "water", - "from": [6.75, 4, 2.75], - "to": [9.25, 4.75, 6], - "rotation": {"angle": 0, "axis": "y", "origin": [4, 5, 8]}, - "faces": { - "north": {"uv": [1, 4, 2.75, 13], "rotation": 90, "texture": "#0"}, - "east": {"uv": [3, 2, 11, 3.75], "texture": "#0"}, - "south": {"uv": [3, 12, 12, 13.75], "texture": "#0"}, - "west": {"uv": [12, 4, 13.75, 12], "rotation": 270, "texture": "#0"}, - "up": {"uv": [3, 4, 6, 8], "texture": "#0"}, - "down": {"uv": [3, 4, 6, 8], "texture": "#0"} - } - }, - { - "from": [3, 3, 14], - "to": [13, 13, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 28, 8]}, - "faces": { - "north": {"uv": [6, 11, 11, 16], "texture": "#1"}, - "east": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, - "south": {"uv": [11, 11, 16, 16], "texture": "#1"}, - "west": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, - "up": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, - "down": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"} - } - } - ] + "credit": "Made with Blockbench", + "textures": { + "0": "minecraft:block/water_still", + "1": "create:block/pipes", + "missing": "minecraft:block/copper_block", + "particle": "minecraft:block/copper_block" + }, + "elements": [ + { + "from": [3, 0, 2], + "to": [13, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [3, 0, 0]}, + "color": 5, + "faces": { + "north": {"uv": [0, 0, 10, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 10, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 10, 14], "texture": "#missing"}, + "down": {"uv": [0, 0, 10, 14], "texture": "#missing"} + } + }, + { + "from": [2, 2, 1], + "to": [14, 4, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [2, 2, 1]}, + "color": 3, + "faces": { + "north": {"uv": [0, 0, 12, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 11, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 12, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 11, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 12, 11], "texture": "#missing"}, + "down": {"uv": [0, 0, 12, 11], "texture": "#missing"} + } + }, + { + "from": [1, 8, 0], + "to": [15, 10, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 8, 0]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "down": {"uv": [0, 0, 14, 2], "texture": "#missing"} + } + }, + { + "from": [1, 8, 11], + "to": [15, 10, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [1, 8, 11]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 14, 2], "texture": "#missing"}, + "down": {"uv": [0, 0, 14, 2], "texture": "#missing"} + } + }, + { + "from": [1, 8, 2], + "to": [3, 10, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [3, 8, 0]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 9, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 9, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 9, 2], "rotation": 90, "texture": "#missing"}, + "down": {"uv": [0, 0, 9, 2], "rotation": 270, "texture": "#missing"} + } + }, + { + "from": [13, 8, 2], + "to": [15, 10, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [15, 8, 0]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 9, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 9, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 9, 2], "rotation": 90, "texture": "#missing"}, + "down": {"uv": [0, 0, 9, 2], "rotation": 270, "texture": "#missing"} + } + }, + { + "from": [2, 2, 12], + "to": [14, 8, 15.75], + "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 13]}, + "color": 1, + "faces": { + "north": {"uv": [0, 0, 12, 6], "texture": "#missing"}, + "east": {"uv": [0, 0, 3.75, 6], "texture": "#missing"}, + "south": {"uv": [0, 0, 12, 6], "texture": "#missing"}, + "west": {"uv": [0, 0, 3.75, 6], "texture": "#missing"}, + "up": {"uv": [0, 0, 12, 3.75], "texture": "#missing"}, + "down": {"uv": [0, 0, 12, 3.75], "texture": "#missing"} + } + }, + { + "from": [2, 8, 13.75], + "to": [14, 19, 15.75], + "rotation": {"angle": 0, "axis": "y", "origin": [2, 8, 14]}, + "faces": { + "north": {"uv": [2, 2, 14, 13], "texture": "#missing"}, + "east": {"uv": [0, 2, 2, 13], "texture": "#missing"}, + "south": {"uv": [2, 2, 14, 13], "texture": "#missing"}, + "west": {"uv": [14, 2, 16, 13], "texture": "#missing"}, + "up": {"uv": [2, 0, 14, 2], "texture": "#missing"}, + "down": {"uv": [2, 13, 14, 15], "texture": "#missing"} + } + }, + { + "from": [1.75, 18.5, 13.5], + "to": [14.25, 20, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [2, 18, 14]}, + "faces": { + "north": {"uv": [0, 0, 12.5, 1.5], "texture": "#missing"}, + "east": {"uv": [0, 0, 2.5, 1.5], "texture": "#missing"}, + "south": {"uv": [1.75, 0.5, 14.25, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 2.5, 1.5], "texture": "#missing"}, + "up": {"uv": [1.75, 7, 14.25, 9.5], "texture": "#missing"}, + "down": {"uv": [0, 0, 12.5, 2.5], "texture": "#missing"} + } + }, + { + "from": [2.5, 10, 12.25], + "to": [13.75, 22, 13.25], + "rotation": {"angle": 0, "axis": "x", "origin": [3, 10, 12.25]}, + "color": 5, + "faces": { + "north": {"uv": [0, 0, 11.25, 12], "texture": "#missing"}, + "east": {"uv": [0, 0, 1, 12], "texture": "#missing"}, + "south": {"uv": [0, 0, 11.25, 12], "texture": "#missing"}, + "west": {"uv": [0, 0, 1, 12], "texture": "#missing"}, + "up": {"uv": [0, 0, 11.25, 1], "texture": "#missing"}, + "down": {"uv": [0, 0, 11.25, 1], "texture": "#missing"} + } + }, + { + "from": [2, 4, 1], + "to": [4, 8, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [2, 6, 1]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "east": {"uv": [0, 0, 11, 4], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "west": {"uv": [0, 0, 11, 4], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 11], "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 11], "texture": "#missing"} + } + }, + { + "from": [12, 4, 1], + "to": [14, 8, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 1]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "east": {"uv": [0, 0, 11, 4], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "west": {"uv": [0, 0, 11, 4], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 11], "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 11], "texture": "#missing"} + } + }, + { + "from": [4, 4, 1], + "to": [12, 8, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 1]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 8, 4], "texture": "#missing"}, + "east": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "south": {"uv": [0, 0, 8, 4], "texture": "#missing"}, + "west": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 8], "rotation": 90, "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 8], "rotation": 270, "texture": "#missing"} + } + }, + { + "from": [4, 4, 10], + "to": [12, 8, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [12, 6, 10]}, + "color": 4, + "faces": { + "north": {"uv": [0, 0, 8, 4], "texture": "#missing"}, + "east": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "south": {"uv": [0, 0, 8, 4], "texture": "#missing"}, + "west": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 8], "rotation": 90, "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 8], "rotation": 270, "texture": "#missing"} + } + }, + { + "from": [4, 4, 7], + "to": [12, 5, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 8]}, + "color": 7, + "faces": { + "north": {"uv": [0, 0, 8, 1], "texture": "#missing"}, + "east": {"uv": [0, 0, 3, 1], "texture": "#missing"}, + "south": {"uv": [0, 0, 8, 1], "texture": "#missing"}, + "west": {"uv": [0, 0, 3, 1], "texture": "#missing"}, + "up": {"uv": [0, 0, 8, 3], "texture": "#missing"}, + "down": {"uv": [0, 0, 8, 3], "texture": "#missing"} + } + }, + { + "from": [4, 4, 3], + "to": [6, 5, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 5]}, + "color": 7, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#missing"}, + "east": {"uv": [0, 0, 4, 1], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#missing"}, + "west": {"uv": [0, 0, 4, 1], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 4], "texture": "#missing"} + } + }, + { + "from": [10, 4, 3], + "to": [12, 5, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 4, 5]}, + "color": 7, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#missing"}, + "east": {"uv": [0, 0, 4, 1], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#missing"}, + "west": {"uv": [0, 0, 4, 1], "texture": "#missing"}, + "up": {"uv": [0, 0, 2, 4], "texture": "#missing"}, + "down": {"uv": [0, 0, 2, 4], "texture": "#missing"} + } + }, + { + "from": [6, 4, 3], + "to": [7, 5.25, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 4, 5]}, + "color": 9, + "faces": { + "north": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "east": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, + "south": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "west": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, + "up": {"uv": [0, 0, 1, 4], "texture": "#missing"}, + "down": {"uv": [0, 0, 1, 4], "texture": "#missing"} + } + }, + { + "from": [7, 4, 6], + "to": [9, 5.25, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 6]}, + "color": 9, + "faces": { + "north": {"uv": [0, 0, 2, 1.25], "texture": "#missing"}, + "east": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "south": {"uv": [0, 0, 2, 1.25], "texture": "#missing"}, + "west": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "up": {"uv": [0, 0, 1, 2], "rotation": 90, "texture": "#missing"}, + "down": {"uv": [0, 0, 1, 2], "rotation": 270, "texture": "#missing"} + } + }, + { + "from": [9, 4, 3], + "to": [10, 5.25, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 4, 5]}, + "color": 9, + "faces": { + "north": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "east": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, + "south": {"uv": [0, 0, 1, 1.25], "texture": "#missing"}, + "west": {"uv": [0, 0, 4, 1.25], "texture": "#missing"}, + "up": {"uv": [0, 0, 1, 4], "texture": "#missing"}, + "down": {"uv": [0, 0, 1, 4], "texture": "#missing"} + } + }, + { + "from": [1, 14.75, 15], + "to": [2, 16.75, 15.5], + "rotation": {"angle": -22.5, "axis": "x", "origin": [0, 14.75, 14.25]}, + "color": 6, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#missing"}, + "east": {"uv": [0, 0, 0.5, 2], "texture": "#missing"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#missing"}, + "west": {"uv": [0, 0, 0.5, 2], "texture": "#missing"}, + "up": {"uv": [0, 0, 1, 0.5], "texture": "#missing"}, + "down": {"uv": [0, 0, 1, 0.5], "texture": "#missing"} + } + }, + { + "name": "water", + "from": [6.75, 4, 2.75], + "to": [9.25, 4.75, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 5, 8]}, + "faces": { + "north": {"uv": [1, 4, 2.75, 13], "rotation": 90, "texture": "#0"}, + "east": {"uv": [3, 2, 11, 3.75], "texture": "#0"}, + "south": {"uv": [3, 12, 12, 13.75], "texture": "#0"}, + "west": {"uv": [12, 4, 13.75, 12], "rotation": 270, "texture": "#0"}, + "up": {"uv": [3, 4, 6, 8], "texture": "#0"}, + "down": {"uv": [3, 4, 6, 8], "texture": "#0"} + } + }, + { + "from": [3, 3, 14], + "to": [13, 13, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 28, 8]}, + "faces": { + "north": {"uv": [6, 11, 11, 16], "texture": "#1"}, + "east": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, + "south": {"uv": [11, 11, 16, 16], "texture": "#1"}, + "west": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, + "up": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"}, + "down": {"uv": [11.5, 18.5, 10.5, 11], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "translation": [0, 4, 0], + "scale": [0.5, 0.5, 0.5] + }, + "thirdperson_lefthand": { + "translation": [0, 4, 0], + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_righthand": { + "scale": [0.5, 0.5, 0.5] + }, + "firstperson_lefthand": { + "scale": [0.5, 0.5, 0.5] + }, + "ground": { + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [28, 130, -1], + "translation": [0, -1.25, 0], + "scale": [0.5, 0.5, 0.5] + }, + "head": { + "translation": [0, 14, 0] + }, + "fixed": { + "translation": [0, 0, -3], + "scale": [0.5, 0.5, 0.5] + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/pissnshit/models/item/flushed.json b/src/main/resources/assets/pissnshit/models/item/flushed.json new file mode 100644 index 0000000..c169f48 --- /dev/null +++ b/src/main/resources/assets/pissnshit/models/item/flushed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "pissnshit:item/flushed" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/pissnshit/models/item/mechanical_toilet.json b/src/main/resources/assets/pissnshit/models/item/mechanical_toilet.json new file mode 100644 index 0000000..db408d1 --- /dev/null +++ b/src/main/resources/assets/pissnshit/models/item/mechanical_toilet.json @@ -0,0 +1,3 @@ +{ + "parent": "pissnshit:block/mechanical_toilet" +} \ No newline at end of file diff --git a/src/main/resources/assets/pissnshit/textures/item/flushed.png b/src/main/resources/assets/pissnshit/textures/item/flushed.png new file mode 100644 index 0000000000000000000000000000000000000000..635e51234c6bad92fceefbc0494806b9b9446a50 GIT binary patch literal 761 zcmVWRc5R|4GD2+8{JOVM+{0piUWFzlW*L-1zDDHo#M9jFJPHDlh#c&FcecvcQkU*p~p`!HvSILnHg@| zuvKxvz~o0R&T}c2hezVePdCJg60pl#cr^F`OR*SQnwuege*v9D8X9`hf9E#bZW(NC z1H!~XqLPSv1!fIqF@D;ER0(uv1=NmKz?p=&H4bSb#PzezHfZJNfMq*ufv*sj6M!uX zbbN|P`0ex)*=r^Wq`q%t0%-k4>T#PK;`Ni(~1R0x`=F{ z>JMFr^v?H@Ux2vj%iYAOuKQT5_F|h?-B046v55 zzFZLn(MK-Y{&l3Z#D+R~KT;XB*o7lQ&l31>2}xh>D&)cELD%}Jw_fap-G-?UM!3U6 rjV2+}4O8-@IePnP^|R)&$-?} Date: Tue, 27 Aug 2024 22:11:15 +0200 Subject: [PATCH 2/4] feat: sitting on toilets --- .../theclashfruit/pissnshit/PissAndShit.java | 5 ++ .../blocks/toilet/MechanicalToiletBlock.java | 26 +++++++++++ .../toilet/MechanicalToiletSeatEntity.java | 46 +++++++++++++++++++ .../pissnshit/client/PissAndShitClient.java | 5 ++ .../MechanicalToiletSeatEntityRenderer.java | 17 +++++++ .../pissnshit/criteria/ToiletUseTrigger.java | 45 ++++++++++++++++++ .../pissnshit/registry/Blocks.java | 22 --------- .../pissnshit/registry/Entities.java | 24 ++++++++++ .../assets/pissnshit/lang/en_us.json | 1 - .../advancements/pissnshit/flushed.json | 5 +- 10 files changed, 169 insertions(+), 27 deletions(-) create mode 100644 src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/client/renderer/MechanicalToiletSeatEntityRenderer.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/criteria/ToiletUseTrigger.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/registry/Entities.java diff --git a/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java b/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java index fe6ee4a..a8364a2 100644 --- a/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java +++ b/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java @@ -5,12 +5,14 @@ import me.shedaniel.autoconfig.AutoConfig; import me.shedaniel.autoconfig.ConfigHolder; import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer; import me.theclashfruit.pissnshit.config.MainConfig; +import me.theclashfruit.pissnshit.criteria.ToiletUseTrigger; import me.theclashfruit.pissnshit.network.PissingPacket; import me.theclashfruit.pissnshit.registry.*; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; import net.fabricmc.fabric.api.loot.v2.LootTableEvents; +import net.minecraft.advancement.criterion.Criteria; import net.minecraft.loot.LootPool; import net.minecraft.loot.condition.RandomChanceLootCondition; import net.minecraft.loot.entry.ItemEntry; @@ -27,6 +29,8 @@ public class PissAndShit implements ModInitializer { public static final GameRules.Key PISS_SOURCE_CONVERSION = GameRuleRegistry.register("pissSourceConversion", GameRules.Category.UPDATES, GameRuleFactory.createBooleanRule(false)); + public static ToiletUseTrigger TOILET_USED = Criteria.register(new ToiletUseTrigger()); + public static MainConfig CONFIG; public static ConfigHolder CONFIG_HOLDER; @@ -37,6 +41,7 @@ public class PissAndShit implements ModInitializer { Fluids.init(); Items.init(); Blocks.init(); + Entities.init(); StatusEffects.init(); Potions.init(); diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java index 8cee95a..93a01c9 100644 --- a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlock.java @@ -8,18 +8,24 @@ import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalFacingBlock; import net.minecraft.block.ShapeContext; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemUsageContext; import net.minecraft.state.StateManager; import net.minecraft.state.property.Properties; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; +import net.minecraft.world.World; import net.minecraft.world.WorldView; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import static me.theclashfruit.pissnshit.PissAndShit.TOILET_USED; import static net.minecraft.state.property.Properties.HORIZONTAL_FACING; public class MechanicalToiletBlock extends HorizontalFacingBlock implements IBE, IWrenchable { @@ -86,6 +92,26 @@ public class MechanicalToiletBlock extends HorizontalFacingBlock implements IBE< return Blocks.MECHANICAL_TOILET_BLOCK_ENTITY; } + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (!world.isClient) { + if (player.hasVehicle()) { + return ActionResult.PASS; + } + + MechanicalToiletSeatEntity seatEntity = MechanicalToiletSeatEntity.create(world, pos); + + world.spawnEntity(seatEntity); + player.startRiding(seatEntity); + + TOILET_USED.trigger(player); + + return ActionResult.SUCCESS; + } + + return ActionResult.PASS; + } + public static VoxelShape rotateShape(Direction from, Direction to, VoxelShape shape) { VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java new file mode 100644 index 0000000..8c72725 --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java @@ -0,0 +1,46 @@ +package me.theclashfruit.pissnshit.blocks.toilet; + +import me.theclashfruit.pissnshit.registry.Entities; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.packet.Packet; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class MechanicalToiletSeatEntity extends Entity { + public MechanicalToiletSeatEntity(EntityType type, World world) { + super(type, world); + + this.noClip = true; // Allows entity to ignore collisions + } + + @Override + protected void initDataTracker() {} + + @Override + protected void readCustomDataFromNbt(NbtCompound nbt) {} + + @Override + protected void writeCustomDataToNbt(NbtCompound nbt) {} + + @Override + public void tick() { + super.tick(); + + if (!getWorld().isClient) { + if (getFirstPassenger() == null || !(getFirstPassenger() instanceof PlayerEntity) || !(getWorld().getBlockState(getBlockPos()).getBlock() instanceof MechanicalToiletBlock)) { + discard(); + } + } + } + + public static MechanicalToiletSeatEntity create(World world, BlockPos pos) { + MechanicalToiletSeatEntity seatEntity = new MechanicalToiletSeatEntity(Entities.MECHANICAL_TOILET_SEAT_ENTITY, world); + + seatEntity.updatePosition(pos.getX() + 0.45, pos.getY() + 0.45, pos.getZ() + 0.45); + + return seatEntity; + } +} diff --git a/src/main/java/me/theclashfruit/pissnshit/client/PissAndShitClient.java b/src/main/java/me/theclashfruit/pissnshit/client/PissAndShitClient.java index 9feeb90..47a3509 100644 --- a/src/main/java/me/theclashfruit/pissnshit/client/PissAndShitClient.java +++ b/src/main/java/me/theclashfruit/pissnshit/client/PissAndShitClient.java @@ -1,9 +1,11 @@ package me.theclashfruit.pissnshit.client; import me.theclashfruit.pissnshit.client.gui.hud.PissAndShitHudOverlay; +import me.theclashfruit.pissnshit.client.renderer.MechanicalToiletSeatEntityRenderer; import me.theclashfruit.pissnshit.network.PissSyncPacket; import me.theclashfruit.pissnshit.network.PissingPacket; import me.theclashfruit.pissnshit.network.ShitSyncPacket; +import me.theclashfruit.pissnshit.registry.Entities; import me.theclashfruit.pissnshit.registry.Fluids; import me.theclashfruit.pissnshit.client.gui.screen.DisclaimerScreen; import net.fabricmc.api.ClientModInitializer; @@ -13,6 +15,7 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.fabricmc.fabric.api.client.render.fluid.v1.SimpleFluidRenderHandler; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; @@ -36,6 +39,8 @@ public class PissAndShitClient implements ClientModInitializer { BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), Fluids.STILL_PISS, Fluids.FLOWING_PISS); + EntityRendererRegistry.register(Entities.MECHANICAL_TOILET_SEAT_ENTITY, MechanicalToiletSeatEntityRenderer::new); + MinecraftClient client = MinecraftClient.getInstance(); PissAndShitHudOverlay hudOverlay = new PissAndShitHudOverlay(client); diff --git a/src/main/java/me/theclashfruit/pissnshit/client/renderer/MechanicalToiletSeatEntityRenderer.java b/src/main/java/me/theclashfruit/pissnshit/client/renderer/MechanicalToiletSeatEntityRenderer.java new file mode 100644 index 0000000..3149c1c --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/client/renderer/MechanicalToiletSeatEntityRenderer.java @@ -0,0 +1,17 @@ +package me.theclashfruit.pissnshit.client.renderer; + +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletSeatEntity; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.util.Identifier; + +public class MechanicalToiletSeatEntityRenderer extends EntityRenderer { + public MechanicalToiletSeatEntityRenderer(EntityRendererFactory.Context context) { + super(context); + } + + @Override + public Identifier getTexture(MechanicalToiletSeatEntity entity) { + return null; + } +} diff --git a/src/main/java/me/theclashfruit/pissnshit/criteria/ToiletUseTrigger.java b/src/main/java/me/theclashfruit/pissnshit/criteria/ToiletUseTrigger.java new file mode 100644 index 0000000..84b7e69 --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/criteria/ToiletUseTrigger.java @@ -0,0 +1,45 @@ +package me.theclashfruit.pissnshit.criteria; + +import com.google.gson.JsonObject; +import com.mojang.serialization.Codec; +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.advancement.criterion.AbstractCriterionConditions; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer; +import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; + +import java.util.Optional; + +import static me.theclashfruit.pissnshit.PissAndShit.MOD_ID; + +public class ToiletUseTrigger extends AbstractCriterion { + public static final Identifier ID = new Identifier(MOD_ID, "toilet_used"); + + @Override + protected Conditions conditionsFromJson(JsonObject obj, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) { + return new Conditions(); + } + + @Override + public Identifier getId() { + return ID; + } + + public void trigger(PlayerEntity player) { + trigger((ServerPlayerEntity) player, Conditions::requirementsMet); + } + + public static class Conditions extends AbstractCriterionConditions { + public Conditions() { + super(ID, LootContextPredicate.EMPTY); + } + + boolean requirementsMet() { + return true; + } + } +} diff --git a/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java b/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java index 01c1b66..da76ab1 100644 --- a/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java +++ b/src/main/java/me/theclashfruit/pissnshit/registry/Blocks.java @@ -46,27 +46,5 @@ public class Blocks { public static final BlockEntityType MECHANICAL_TOILET_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier(MOD_ID, "mechanical_toilet_block_entity"), BlockEntityType.Builder.create(MechanicalToiletBlockEntity::new, MECHANICAL_TOILET).build(null)); - /* - REGISTRATE - .block("encased_fan", MechanicalToiletBlock::new) - .initialProperties(SharedProperties::copperMetal) - .properties(p -> p.mapColor(MapColor.ORANGE)) - .blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p))) - .transform(BlockStressDefaults.setImpact(8.0)) - .item() - .transform(customItemModel()) - .addLayer(() -> RenderLayer::getCutout) - .register(); - */ - - /* - public static final BlockEntityEntry MECHANICAL_TOILET_ENTITY = REGISTRATE - .blockEntity("encased_fan", MechanicalToiletBlockEntity::new) - .instance(() -> MechanicalToiletCogInstance::new) - .validBlocks(MECHANICAL_TOILET) - .renderer(() -> MechanicalToiletRenderer::new) - .register(); - */ - public static void init() {} } diff --git a/src/main/java/me/theclashfruit/pissnshit/registry/Entities.java b/src/main/java/me/theclashfruit/pissnshit/registry/Entities.java new file mode 100644 index 0000000..afee3ed --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/registry/Entities.java @@ -0,0 +1,24 @@ +package me.theclashfruit.pissnshit.registry; + +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletSeatEntity; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.EntityDimensions; +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; + +import static me.theclashfruit.pissnshit.PissAndShit.MOD_ID; + +public class Entities { + public static final EntityType MECHANICAL_TOILET_SEAT_ENTITY = Registry.register( + Registries.ENTITY_TYPE, + new Identifier(MOD_ID, "mechanical_toilet_seat_entity"), + FabricEntityTypeBuilder.create(SpawnGroup.MISC, MechanicalToiletSeatEntity::new) + .dimensions(EntityDimensions.fixed(0.001f, 0.001f)) + .build() + ); + + public static void init() {} +} diff --git a/src/main/resources/assets/pissnshit/lang/en_us.json b/src/main/resources/assets/pissnshit/lang/en_us.json index 6c9df84..cc39863 100644 --- a/src/main/resources/assets/pissnshit/lang/en_us.json +++ b/src/main/resources/assets/pissnshit/lang/en_us.json @@ -42,7 +42,6 @@ "advancements.pissnshit.mechanical_marvel.title": "Mechanical Marvel", "advancements.pissnshit.mechanical_marvel.description": "Craft a mechanical toilet.", - "advancements.pissnshit.flushed.title": "Flush(ed)", "advancements.pissnshit.flushed.description": "Use your newly operational mechanical toilet.", diff --git a/src/main/resources/data/minecraft/advancements/pissnshit/flushed.json b/src/main/resources/data/minecraft/advancements/pissnshit/flushed.json index 36e23c5..812a38e 100644 --- a/src/main/resources/data/minecraft/advancements/pissnshit/flushed.json +++ b/src/main/resources/data/minecraft/advancements/pissnshit/flushed.json @@ -17,10 +17,7 @@ "parent": "minecraft:pissnshit/mechanical_marvel", "criteria": { "mechanical_toilet": { - "conditions": { - "recipe_id": "pissnshit:mechanical_toilet" - }, - "trigger": "minecraft:recipe_crafted" + "trigger": "pissnshit:toilet_used" } }, "requirements": [ From e79a41fe2c22e1600d24d09dc3274cd5616f3c1e Mon Sep 17 00:00:00 2001 From: TheClashFruit Date: Tue, 27 Aug 2024 22:45:59 +0200 Subject: [PATCH 3/4] feat: toilets now suck piss & shit out of players --- .../toilet/MechanicalToiletBlockEntity.java | 12 ++++++++++- .../toilet/MechanicalToiletSeatEntity.java | 19 ++++++++++++++++++ .../pissnshit/util/PissManager.java | 20 +++++++++++++++++++ .../pissnshit/util/ShitManager.java | 11 ++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java index 7463c66..02aa195 100644 --- a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletBlockEntity.java @@ -14,10 +14,12 @@ import io.github.fabricators_of_create.porting_lib.fluids.FluidStack; import io.github.fabricators_of_create.porting_lib.util.FluidTextUtil; import io.github.fabricators_of_create.porting_lib.util.FluidUnit; import me.theclashfruit.pissnshit.registry.Blocks; +import me.theclashfruit.pissnshit.registry.Fluids; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.fabricmc.fabric.api.transfer.v1.storage.Storage; import net.fabricmc.fabric.api.transfer.v1.storage.base.SidedStorageBlockEntity; +import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.text.Text; @@ -31,6 +33,8 @@ import javax.annotation.Nullable; import java.awt.*; import java.util.List; +import static com.simibubi.create.content.kinetics.BlockStressValues.getCapacity; + public class MechanicalToiletBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation, SidedStorageBlockEntity { private SmartFluidTankBehaviour tank; @@ -40,7 +44,7 @@ public class MechanicalToiletBlockEntity extends SmartBlockEntity implements IHa @Override public void addBehaviours(List behaviours) { - tank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, FluidConstants.BUCKET, true) + tank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 1, FluidConstants.BUCKET, true) .forbidInsertion(); behaviours.add(tank); @@ -93,4 +97,10 @@ public class MechanicalToiletBlockEntity extends SmartBlockEntity implements IHa return true; } + + public void addPiss(int amount) { + for (SmartFluidTankBehaviour.TankSegment tank : tank.getTanks()) { + tank.getTank().setFluid(new FluidStack(FluidVariant.of(Fluids.STILL_PISS), tank.getTank().getFluid().getAmount() + amount)); + } + } } diff --git a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java index 8c72725..341252a 100644 --- a/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java +++ b/src/main/java/me/theclashfruit/pissnshit/blocks/toilet/MechanicalToiletSeatEntity.java @@ -1,6 +1,9 @@ package me.theclashfruit.pissnshit.blocks.toilet; +import me.theclashfruit.pissnshit.mixin.PlayerEntityMixin; import me.theclashfruit.pissnshit.registry.Entities; +import me.theclashfruit.pissnshit.util.PlayerEntityUtil; +import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; @@ -10,6 +13,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class MechanicalToiletSeatEntity extends Entity { + public BlockPos toiletPos; + public MechanicalToiletSeatEntity(EntityType type, World world) { super(type, world); @@ -29,10 +34,23 @@ public class MechanicalToiletSeatEntity extends Entity { public void tick() { super.tick(); + Block block = getWorld().getBlockState(getBlockPos()).getBlock(); + + if (!(block instanceof MechanicalToiletBlock)) { + discard(); + + return; + } + if (!getWorld().isClient) { if (getFirstPassenger() == null || !(getFirstPassenger() instanceof PlayerEntity) || !(getWorld().getBlockState(getBlockPos()).getBlock() instanceof MechanicalToiletBlock)) { discard(); } + + if (getFirstPassenger() instanceof PlayerEntity player) { + ((PlayerEntityUtil) player).getPissManager().pissOnToilet(player, ((MechanicalToiletBlock) block), toiletPos); + ((PlayerEntityUtil) player).getShitManager().shitOnToilet(player, ((MechanicalToiletBlock) block), toiletPos); + } } } @@ -40,6 +58,7 @@ public class MechanicalToiletSeatEntity extends Entity { MechanicalToiletSeatEntity seatEntity = new MechanicalToiletSeatEntity(Entities.MECHANICAL_TOILET_SEAT_ENTITY, world); seatEntity.updatePosition(pos.getX() + 0.45, pos.getY() + 0.45, pos.getZ() + 0.45); + seatEntity.toiletPos = pos; return seatEntity; } diff --git a/src/main/java/me/theclashfruit/pissnshit/util/PissManager.java b/src/main/java/me/theclashfruit/pissnshit/util/PissManager.java index 274b037..e26459f 100644 --- a/src/main/java/me/theclashfruit/pissnshit/util/PissManager.java +++ b/src/main/java/me/theclashfruit/pissnshit/util/PissManager.java @@ -1,5 +1,7 @@ package me.theclashfruit.pissnshit.util; +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletBlock; +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletBlockEntity; import me.theclashfruit.pissnshit.network.PissSyncPacket; import me.theclashfruit.pissnshit.registry.DamageTypes; import net.minecraft.entity.player.PlayerEntity; @@ -7,6 +9,9 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Position; +import net.minecraft.world.World; import static me.theclashfruit.pissnshit.PissAndShit.CONFIG; @@ -78,6 +83,21 @@ public class PissManager { } } + public void pissOnToilet(PlayerEntity player, MechanicalToiletBlock toiletBlock, BlockPos toiletPos) { + World world = player.getWorld(); + + if (pissLevel >= 1) { + this.pissLevel -= 1; + + if (world.getBlockEntity(toiletPos) instanceof MechanicalToiletBlockEntity toiletEntity) { + toiletEntity.addPiss(10); + } + } + + // Sync Piss Level + PissSyncPacket.sendToClient((ServerPlayerEntity) player, this.pissLevel); + } + public void readNbt(NbtCompound nbt) { if (nbt.contains("pissLevel", NbtElement.NUMBER_TYPE)) { this.pissLevel = nbt.getInt("pissLevel"); diff --git a/src/main/java/me/theclashfruit/pissnshit/util/ShitManager.java b/src/main/java/me/theclashfruit/pissnshit/util/ShitManager.java index ef61cc5..65d081a 100644 --- a/src/main/java/me/theclashfruit/pissnshit/util/ShitManager.java +++ b/src/main/java/me/theclashfruit/pissnshit/util/ShitManager.java @@ -1,5 +1,6 @@ package me.theclashfruit.pissnshit.util; +import me.theclashfruit.pissnshit.blocks.toilet.MechanicalToiletBlock; import me.theclashfruit.pissnshit.network.ShitSyncPacket; import me.theclashfruit.pissnshit.registry.DamageTypes; import me.theclashfruit.pissnshit.registry.StatusEffects; @@ -12,6 +13,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.math.BlockPos; import static me.theclashfruit.pissnshit.PissAndShit.CONFIG; import static me.theclashfruit.pissnshit.PissAndShit.LOGGER; @@ -77,6 +79,15 @@ public class ShitManager { } } + public void shitOnToilet(PlayerEntity player, MechanicalToiletBlock toiletBlock, BlockPos toiletPos) { + if (shitLevel >= 1) { + this.shitLevel -= 1; + } + + // Sync Shit Level + ShitSyncPacket.sendToClient((ServerPlayerEntity) player, this.shitLevel); + } + public void readNbt(NbtCompound nbt) { if (nbt.contains("shitLevel", NbtElement.NUMBER_TYPE)) { this.shitTickTimer = nbt.getInt("shitTickTimer"); From 367a202c8c585b8195b0b40b03963588f28b1156 Mon Sep 17 00:00:00 2001 From: TheClashFruit Date: Tue, 27 Aug 2024 23:29:26 +0200 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=F0=9F=98=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../theclashfruit/pissnshit/PissAndShit.java | 3 ++ .../pissnshit/mixin/MinecraftClientMixin.java | 16 +++++++ .../pissnshit/mixin/TextRendererMixin.java | 45 +++++++++++++++++++ .../pissnshit/util/FlushedUtil.java | 39 ++++++++++++++++ src/main/resources/pissnshit.mixins.json | 4 +- 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/theclashfruit/pissnshit/mixin/MinecraftClientMixin.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/mixin/TextRendererMixin.java create mode 100644 src/main/java/me/theclashfruit/pissnshit/util/FlushedUtil.java diff --git a/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java b/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java index a8364a2..462078f 100644 --- a/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java +++ b/src/main/java/me/theclashfruit/pissnshit/PissAndShit.java @@ -8,6 +8,7 @@ import me.theclashfruit.pissnshit.config.MainConfig; import me.theclashfruit.pissnshit.criteria.ToiletUseTrigger; import me.theclashfruit.pissnshit.network.PissingPacket; import me.theclashfruit.pissnshit.registry.*; +import me.theclashfruit.pissnshit.util.FlushedUtil; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; @@ -70,6 +71,8 @@ public class PissAndShit implements ModInitializer { } }); + LOGGER.info(FlushedUtil.flushify("Hello, World!")); + // Register Packets PissingPacket.register(); } diff --git a/src/main/java/me/theclashfruit/pissnshit/mixin/MinecraftClientMixin.java b/src/main/java/me/theclashfruit/pissnshit/mixin/MinecraftClientMixin.java new file mode 100644 index 0000000..cd2e8a5 --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/mixin/MinecraftClientMixin.java @@ -0,0 +1,16 @@ +package me.theclashfruit.pissnshit.mixin; + +import me.theclashfruit.pissnshit.util.FlushedUtil; +import net.minecraft.client.MinecraftClient; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(method = "tick", at = @At("TAIL")) + private void tick(CallbackInfo info) { + FlushedUtil.tick(); + } +} \ No newline at end of file diff --git a/src/main/java/me/theclashfruit/pissnshit/mixin/TextRendererMixin.java b/src/main/java/me/theclashfruit/pissnshit/mixin/TextRendererMixin.java new file mode 100644 index 0000000..31f1d0f --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/mixin/TextRendererMixin.java @@ -0,0 +1,45 @@ +package me.theclashfruit.pissnshit.mixin; + +import me.theclashfruit.pissnshit.util.FlushedUtil; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.text.OrderedText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import static me.theclashfruit.pissnshit.PissAndShit.LOGGER; + +@Mixin(TextRenderer.class) +public class TextRendererMixin { + @ModifyVariable( + method = "drawLayer(Ljava/lang/String;FFIZLorg/joml/Matrix4f;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/client/font/TextRenderer$TextLayerType;II)F", + at = @At( + value = "HEAD", + ordinal = 0 + ), + argsOnly = true + ) + private String modifyString(String text) { + if (FlushedUtil.isEnabled()) + return FlushedUtil.flushify(text); + else + return text; + } + + /* TODO: Somehow make it so I can use the flushed emoji with this one too... + @ModifyVariable( + method = "drawLayer(Lnet/minecraft/text/OrderedText;FFIZLorg/joml/Matrix4f;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/client/font/TextRenderer$TextLayerType;II)F", + at = @At( + value = "HEAD", + ordinal = 0 + ), + argsOnly = true + ) + private OrderedText modifyString(OrderedText text) { + if (FlushedUtil.isEnabled()) + return new FlushedOrderedText(text); + else + return text; + } + */ +} diff --git a/src/main/java/me/theclashfruit/pissnshit/util/FlushedUtil.java b/src/main/java/me/theclashfruit/pissnshit/util/FlushedUtil.java new file mode 100644 index 0000000..77f9109 --- /dev/null +++ b/src/main/java/me/theclashfruit/pissnshit/util/FlushedUtil.java @@ -0,0 +1,39 @@ +package me.theclashfruit.pissnshit.util; + +import me.theclashfruit.pissnshit.registry.Items; +import net.minecraft.client.MinecraftClient; +import net.minecraft.item.ItemStack; + +import java.util.regex.Pattern; + +public class FlushedUtil { + private static boolean isEnabled = false; + + public static void tick() { + MinecraftClient client = MinecraftClient.getInstance(); + + if (client.player == null) { + isEnabled = false; + + return; + } + + isEnabled = client.player.getInventory().contains( + new ItemStack(Items.FLUSHED) + ); + } + + public static String flushify(String input) { + input = Pattern.compile("([A-Za-zÀ-ÖØ-öø-ÿőű]+)").matcher(input).replaceAll(m -> { + String group = m.group(); + + return "😳".repeat(group.length()); + }); + + return input; + } + + public static boolean isEnabled() { + return isEnabled; + } +} diff --git a/src/main/resources/pissnshit.mixins.json b/src/main/resources/pissnshit.mixins.json index f085f93..0eee39a 100644 --- a/src/main/resources/pissnshit.mixins.json +++ b/src/main/resources/pissnshit.mixins.json @@ -8,7 +8,9 @@ "PlayerEntityMixin" ], "client": [ - "InGameHudMixin" + "InGameHudMixin", + "MinecraftClientMixin", + "TextRendererMixin" ], "injectors": { "defaultRequire": 1