From b1a0f25f4bf6661eb48c0c2532d92768114aa7f4 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 15 Feb 2020 18:54:23 +0100 Subject: [PATCH] Clockwork Bearing and Rope Pulley - Stationary Contraption Entities no longer sync positions like normal entities - Flimsy attempts at making linear contraption movement smoother, especially at differing tick speeds between server and client - Added slot covers for the Mechanical Crafter - Added the Clockwork Bearing - Added the Rope Pulley - Server speed no longer tries to sync when game is paused - Fixed crash when moving block breakers are loaded in while stalled - Fixed Cuckoo Clock's angle interpolation when tps is low --- .../com/simibubi/create/AllBlockPartials.java | 5 +- .../java/com/simibubi/create/AllBlocks.java | 10 +- .../java/com/simibubi/create/AllEntities.java | 12 +- .../java/com/simibubi/create/AllItems.java | 1 + .../com/simibubi/create/AllParticles.java | 2 +- .../com/simibubi/create/AllTileEntities.java | 11 +- .../com/simibubi/create/config/CKinetics.java | 2 + .../create/config/StressConfigDefaults.java | 4 +- .../create/foundation/utility/AllShapes.java | 13 +- .../foundation/utility/AngleHelper.java | 14 + .../utility/ServerSpeedProvider.java | 7 + .../base/HorizontalAxisKineticBlock.java | 107 ++++++ .../BlockBreakingMovementBehaviour.java | 6 + .../clock/CuckooClockTileEntity.java | 35 +- .../components/contraptions/Contraption.java | 33 +- .../contraptions/ContraptionEntity.java | 68 ++-- .../contraptions/MovementContext.java | 6 +- .../contraptions/bearing/BearingBlock.java | 43 +++ .../bearing/BearingContraption.java | 13 +- ...er.java => BearingTileEntityRenderer.java} | 8 +- .../bearing/ClockworkBearingBlock.java | 14 + .../bearing/ClockworkBearingTileEntity.java | 266 +++++++++++++++ .../bearing/ClockworkContraption.java | 122 +++++++ .../bearing/IBearingTileEntity.java | 9 + .../bearing/MechanicalBearingBlock.java | 37 +- .../bearing/MechanicalBearingTileEntity.java | 21 +- .../mounted/CartAssemblerBlock.java | 8 +- .../mounted/MountedContraption.java | 11 + .../piston/LinearActuatorTileEntity.java | 201 +++++++++++ .../piston/MechanicalPistonTileEntity.java | 155 ++------- .../piston/PistonContraption.java | 10 + .../contraptions/pulley/PulleyBlock.java | 115 +++++++ .../pulley/PulleyContraption.java | 49 +++ .../contraptions/pulley/PulleyRenderer.java | 75 ++++ .../contraptions/pulley/PulleyTileEntity.java | 129 +++++++ .../crafter/MechanicalCrafterBlock.java | 43 ++- .../crafter/MechanicalCrafterTileEntity.java | 7 +- .../MechanicalCrafterTileEntityRenderer.java | 2 +- .../relays/encased/EncasedBeltBlock.java | 3 +- .../create/blockstates/clockwork_bearing.json | 16 + .../blockstates/mechanical_bearing.json | 2 +- .../create/blockstates/pulley_magnet.json | 5 + .../assets/create/blockstates/rope.json | 5 + .../create/blockstates/rope_pulley.json | 12 + .../resources/assets/create/lang/en_us.json | 8 + .../models/block/bearing/clockwork.json | 9 + .../regular.json} | 0 .../top.json} | 0 .../create/models/block/pulley/casing.json | 195 +++++++++++ .../create/models/block/pulley/item.json | 323 ++++++++++++++++++ .../create/models/block/pulley/magnet.json | 37 ++ .../create/models/block/pulley/rope.json | 24 ++ .../create/models/block/pulley/rope_coil.json | 66 ++++ .../create/models/block/pulley/rope_half.json | 24 ++ .../models/block/pulley/rope_half_magnet.json | 37 ++ .../create/models/item/clockwork_bearing.json | 9 + .../create/models/item/rope_pulley.json | 3 + .../assets/create/models/item/slot_cover.json | 6 + .../textures/block/clockwork_bearing_side.png | Bin 0 -> 500 bytes .../create/textures/block/pulley_casing.png | Bin 0 -> 383 bytes .../create/textures/block/pulley_magnet.png | Bin 0 -> 542 bytes .../create/textures/block/pulley_rope.png | Bin 0 -> 320 bytes .../create/textures/item/slot_cover.png | Bin 0 -> 325 bytes .../loot_tables/blocks/clockwork_bearing.json | 19 ++ .../loot_tables/blocks/rope_pulley.json | 19 ++ .../contraptions/clockwork_bearing.json | 32 ++ .../contraptions/mechanical_crafter.json | 2 +- .../contraptions/rope_pulley.json | 32 ++ .../recipes/crafting_shaped/slot_cover.json | 21 ++ 69 files changed, 2315 insertions(+), 268 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingBlock.java rename src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/{MechanicalBearingTileEntityRenderer.java => BearingTileEntityRenderer.java} (81%) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/IBearingTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java create mode 100644 src/main/resources/assets/create/blockstates/clockwork_bearing.json create mode 100644 src/main/resources/assets/create/blockstates/pulley_magnet.json create mode 100644 src/main/resources/assets/create/blockstates/rope.json create mode 100644 src/main/resources/assets/create/blockstates/rope_pulley.json create mode 100644 src/main/resources/assets/create/models/block/bearing/clockwork.json rename src/main/resources/assets/create/models/block/{mechanical_bearing_base.json => bearing/regular.json} (100%) rename src/main/resources/assets/create/models/block/{mechanical_bearing_top.json => bearing/top.json} (100%) create mode 100644 src/main/resources/assets/create/models/block/pulley/casing.json create mode 100644 src/main/resources/assets/create/models/block/pulley/item.json create mode 100644 src/main/resources/assets/create/models/block/pulley/magnet.json create mode 100644 src/main/resources/assets/create/models/block/pulley/rope.json create mode 100644 src/main/resources/assets/create/models/block/pulley/rope_coil.json create mode 100644 src/main/resources/assets/create/models/block/pulley/rope_half.json create mode 100644 src/main/resources/assets/create/models/block/pulley/rope_half_magnet.json create mode 100644 src/main/resources/assets/create/models/item/clockwork_bearing.json create mode 100644 src/main/resources/assets/create/models/item/rope_pulley.json create mode 100644 src/main/resources/assets/create/models/item/slot_cover.json create mode 100644 src/main/resources/assets/create/textures/block/clockwork_bearing_side.png create mode 100644 src/main/resources/assets/create/textures/block/pulley_casing.png create mode 100644 src/main/resources/assets/create/textures/block/pulley_magnet.png create mode 100644 src/main/resources/assets/create/textures/block/pulley_rope.png create mode 100644 src/main/resources/assets/create/textures/item/slot_cover.png create mode 100644 src/main/resources/data/create/loot_tables/blocks/clockwork_bearing.json create mode 100644 src/main/resources/data/create/loot_tables/blocks/rope_pulley.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/contraptions/clockwork_bearing.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/contraptions/rope_pulley.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/slot_cover.json diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 3c4f41844..6b8f9ace1 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -40,7 +40,7 @@ public enum AllBlockPartials { GAUGE_INDICATOR("gauge/indicator"), GAUGE_HEAD_SPEED("gauge/speed"), GAUGE_HEAD_STRESS("gauge/stress"), - MECHANICAL_BEARING_TOP, + MECHANICAL_BEARING_TOP("bearing/top"), DRILL, HARVESTER_BLADE, DEPLOYER_POLE("deployer/pole"), @@ -64,6 +64,9 @@ public enum AllBlockPartials { CUCKOO_RIGHT_DOOR("cuckoo_clock/right_door"), CUCKOO_PIG("cuckoo_clock/pig"), CUCKOO_CREEPER("cuckoo_clock/creeper"), + ROPE_COIL("pulley/rope_coil"), + ROPE_HALF("pulley/rope_half"), + ROPE_HALF_MAGNET("pulley/rope_half_magnet"), ; diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 5614a73f4..041711955 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -12,6 +12,7 @@ import com.simibubi.create.modules.contraptions.components.actors.DrillBlock; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.clock.CuckooClockBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.LinearChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.RadialChassisBlock; @@ -20,6 +21,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.mounted. import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterBlock; import com.simibubi.create.modules.contraptions.components.crank.HandCrankBlock; import com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelBlock; @@ -138,6 +140,12 @@ public enum AllBlocks { MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()), PISTON_POLE(new PistonPoleBlock()), MECHANICAL_BEARING(new MechanicalBearingBlock()), + CLOCKWORK_BEARING(new ClockworkBearingBlock()), + ROPE_PULLEY(new PulleyBlock()), + ROPE(new PulleyBlock.RopeBlock()), + PULLEY_MAGNET(new PulleyBlock.MagnetBlock()), + CART_ASSEMBLER(new CartAssemblerBlock()), + MINECART_ANCHOR(new MinecartAnchorBlock()), TRANSLATION_CHASSIS(new LinearChassisBlock()), TRANSLATION_CHASSIS_SECONDARY(new LinearChassisBlock()), ROTATION_CHASSIS(new RadialChassisBlock()), @@ -146,8 +154,6 @@ public enum AllBlocks { HARVESTER(new HarvesterBlock()), DEPLOYER(new DeployerBlock()), PORTABLE_STORAGE_INTERFACE(new PortableStorageInterfaceBlock()), - CART_ASSEMBLER(new CartAssemblerBlock()), - MINECART_ANCHOR(new MinecartAnchorBlock()), ANALOG_LEVER(new AnalogLeverBlock()), ANDESITE_CASING(new CasingBlock("andesite_casing")), diff --git a/src/main/java/com/simibubi/create/AllEntities.java b/src/main/java/com/simibubi/create/AllEntities.java index 9dd3c330f..0ab3eeb39 100644 --- a/src/main/java/com/simibubi/create/AllEntities.java +++ b/src/main/java/com/simibubi/create/AllEntities.java @@ -2,6 +2,7 @@ package com.simibubi.create; import java.util.function.Function; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer; @@ -18,7 +19,8 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry; public enum AllEntities { - CONTRAPTION(ContraptionEntity::new, 30, 3, ContraptionEntity::build), + CONTRAPTION(ContraptionEntity::new, 30, 3, true, ContraptionEntity::build), + STATIONARY_CONTRAPTION(ContraptionEntity::new, 30, 40, false, ContraptionEntity::build), ; @@ -27,24 +29,26 @@ public enum AllEntities { private int updateFrequency; private Function, EntityType.Builder> propertyBuilder; private EntityClassification group; + private boolean sendVelocity; public EntityType type; - private AllEntities(IFactory factory, int range, int updateFrequency, + private AllEntities(IFactory factory, int range, int updateFrequency, boolean sendVelocity, Function, EntityType.Builder> propertyBuilder) { this.factory = factory; this.range = range; this.updateFrequency = updateFrequency; + this.sendVelocity = sendVelocity; this.propertyBuilder = propertyBuilder; } public static void register(final RegistryEvent.Register> event) { for (AllEntities entity : values()) { - String id = entity.name().toLowerCase(); + String id = Lang.asId(entity.name()); ResourceLocation resourceLocation = new ResourceLocation(Create.ID, id); Builder builder = EntityType.Builder.create(entity.factory, entity.group) .setTrackingRange(entity.range).setUpdateInterval(entity.updateFrequency) - .setShouldReceiveVelocityUpdates(true); + .setShouldReceiveVelocityUpdates(entity.sendVelocity); if (entity.propertyBuilder != null) builder = entity.propertyBuilder.apply(builder); entity.type = builder.build(id).setRegistryName(resourceLocation); diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index 9c7504c81..9209050bc 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -84,6 +84,7 @@ public enum AllItems { PROPELLER, WHISK, BRASS_HAND, + SLOT_COVER, WRENCH(WrenchItem::new), GOGGLES(GogglesItem::new), diff --git a/src/main/java/com/simibubi/create/AllParticles.java b/src/main/java/com/simibubi/create/AllParticles.java index fda759efa..be412e54b 100644 --- a/src/main/java/com/simibubi/create/AllParticles.java +++ b/src/main/java/com/simibubi/create/AllParticles.java @@ -28,7 +28,7 @@ public enum AllParticles { private ParticleEntry entry; private AllParticles(Supplier> typeFactory) { - String asId = Lang.asId(this.name().toLowerCase()); + String asId = Lang.asId(this.name()); entry = new ParticleEntry(new ResourceLocation(Create.ID, asId), typeFactory); } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 63ba780a5..5ce5a9ebe 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -11,11 +11,14 @@ import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileE import com.simibubi.create.modules.contraptions.components.actors.HarvesterTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.clock.CuckooClockRenderer; import com.simibubi.create.modules.contraptions.components.clock.CuckooClockTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingTileEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity; -import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCrafterTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.crank.HandCrankTileEntity; @@ -114,6 +117,8 @@ public enum AllTileEntities { BELT_TUNNEL(BeltTunnelTileEntity::new, AllBlocks.BELT_TUNNEL), MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON), MECHANICAL_BEARING(MechanicalBearingTileEntity::new, AllBlocks.MECHANICAL_BEARING), + CLOCKWORK_BEARING(ClockworkBearingTileEntity::new, AllBlocks.CLOCKWORK_BEARING), + ROPE_PULLEY(PulleyTileEntity::new, AllBlocks.ROPE_PULLEY), CHASSIS(ChassisTileEntity::new, AllBlocks.ROTATION_CHASSIS, AllBlocks.TRANSLATION_CHASSIS, AllBlocks.TRANSLATION_CHASSIS_SECONDARY), DRILL(DrillTileEntity::new, AllBlocks.DRILL), @@ -200,7 +205,9 @@ public enum AllTileEntities { bind(AnalogLeverTileEntity.class, new AnalogLeverTileEntityRenderer()); bind(MechanicalPistonTileEntity.class, new MechanicalPistonTileEntityRenderer()); - bind(MechanicalBearingTileEntity.class, new MechanicalBearingTileEntityRenderer()); + bind(MechanicalBearingTileEntity.class, new BearingTileEntityRenderer()); + bind(ClockworkBearingTileEntity.class, new BearingTileEntityRenderer()); + bind(PulleyTileEntity.class, new PulleyRenderer()); bind(HarvesterTileEntity.class, new HarvesterTileEntityRenderer()); bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer()); diff --git a/src/main/java/com/simibubi/create/config/CKinetics.java b/src/main/java/com/simibubi/create/config/CKinetics.java index 47383e45b..9571de80b 100644 --- a/src/main/java/com/simibubi/create/config/CKinetics.java +++ b/src/main/java/com/simibubi/create/config/CKinetics.java @@ -22,6 +22,7 @@ public class CKinetics extends ConfigBase { public ConfigInt maxChassisForRotation = i(16, 1, "maxChassisForRotation", Comments.maxChassisForRotation); public ConfigInt maxChassisRange = i(16, 1, "maxChassisRange", Comments.maxChassisRange); public ConfigInt maxPistonPoles = i(64, 1, "maxPistonPoles", Comments.maxPistonPoles); + public ConfigInt maxRopeLength = i(128, 1, "maxRopeLength", Comments.maxRopeLength); public ConfigGroup state = group(0, "stats", Comments.stats); public ConfigFloat mediumSpeed = f(30, 0, 4096, "mediumSpeed", Comments.rpm, Comments.mediumSpeed); @@ -54,6 +55,7 @@ public class CKinetics extends ConfigBase { static String maxChassisForRotation = "Maximum amount of chassis blocks movable by a Mechanical Bearing."; static String maxChassisRange = "Maximum value of a chassis attachment range."; static String maxPistonPoles = "Maximum amount of extension poles behind a Mechanical Piston."; + static String maxRopeLength = "Max length of rope available off a Rope Pulley."; static String stats = "Configure speed/capacity levels for requirements and indicators."; static String rpm = "[in Revolutions per Minute]"; static String su = "[in Stress Units]"; diff --git a/src/main/java/com/simibubi/create/config/StressConfigDefaults.java b/src/main/java/com/simibubi/create/config/StressConfigDefaults.java index 141b3694b..cd7115832 100644 --- a/src/main/java/com/simibubi/create/config/StressConfigDefaults.java +++ b/src/main/java/com/simibubi/create/config/StressConfigDefaults.java @@ -37,12 +37,14 @@ public class StressConfigDefaults { case ENCASED_FAN: case MECHANICAL_MIXER: - case MECHANICAL_BEARING: case MECHANICAL_CRAFTER: return 8; case TURNTABLE: case MECHANICAL_PISTON: + case MECHANICAL_BEARING: + case CLOCKWORK_BEARING: + case ROPE_PULLEY: case STICKY_MECHANICAL_PISTON: return 4; diff --git a/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java b/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java index 8a61fb1f0..b36025466 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AllShapes.java @@ -36,7 +36,11 @@ public class AllShapes { makeCuboidShape(0, 0, 9, 16, 16, 14)), Direction.SOUTH), PORTABLE_STORAGE_INTERFACE = VoxelShaper.forDirectional(VoxelShapes.or( makeCuboidShape(0, 0, 0, 16, 12, 16), - makeCuboidShape(3, 12, 3, 13, 16, 13)), Direction.UP) + makeCuboidShape(3, 12, 3, 13, 16, 13)), Direction.UP), + PULLEY = VoxelShaper.forHorizontalAxis(VoxelShapes.or( + makeCuboidShape(0, 0, 0, 16, 16, 2), + makeCuboidShape(1, 1, 2, 15, 15, 14), + makeCuboidShape(0, 0, 14, 16, 16, 16)), Direction.SOUTH) ; @@ -114,8 +118,11 @@ public class AllShapes { BELT_COLLISION_MASK = makeCuboidShape(0, 0, 0, 16, 19, 16), SCHEMATICANNON_SHAPE = VoxelShapes.or( makeCuboidShape(1, 0, 1, 15, 8, 15), - makeCuboidShape(0.5, 8, 0.5, 15.5, 11, 15.5)) - + makeCuboidShape(0.5, 8, 0.5, 15.5, 11, 15.5)), + PULLEY_MAGNET = VoxelShapes.or( + makeCuboidShape(3, 0, 3, 13, 2, 13), + FOUR_VOXEL_POLE.get(Direction.UP)) + ; diff --git a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 65d3bb133..058c23c1e 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -19,5 +19,19 @@ public class AngleHelper { public static float rad(float angle) { return (float) (angle / 180 * Math.PI); } + + public static float deg(float angle) { + return (float) (angle * 180 / Math.PI); + } + + public static float angleLerp(float pct, float current, float target) { + return current + getShortestAngleDiff(current, target) * pct; + } + + public static float getShortestAngleDiff(double current, double target) { + current = current % 360; + target = target % 360; + return (float) (((((target - current) % 360) + 540) % 360) - 180); + } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/ServerSpeedProvider.java b/src/main/java/com/simibubi/create/foundation/utility/ServerSpeedProvider.java index 176d824d8..b378eca67 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ServerSpeedProvider.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ServerSpeedProvider.java @@ -7,7 +7,10 @@ import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.packet.SimplePacketBase; +import net.minecraft.client.Minecraft; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -38,10 +41,14 @@ public class ServerSpeedProvider { return AllConfigs.SERVER.tickrateSyncTimer.get(); } + @OnlyIn(Dist.CLIENT) @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { if (event.phase == Phase.START) return; + if (Minecraft.getInstance().isSingleplayer() && Minecraft.getInstance().isGamePaused()) + return; + modifier.tick(); clientTimer++; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java new file mode 100644 index 000000000..921edff95 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java @@ -0,0 +1,107 @@ +package com.simibubi.create.modules.contraptions.base; + +import com.simibubi.create.modules.contraptions.RotationPropagator; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemUseContext; +import net.minecraft.state.IProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; + +public abstract class HorizontalAxisKineticBlock extends KineticBlock { + + public static final IProperty HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS; + + public HorizontalAxisKineticBlock(Properties properties) { + super(properties); + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(HORIZONTAL_AXIS); + super.fillStateContainer(builder); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + Axis preferredAxis = getPreferredHorizontalAxis(context); + if (preferredAxis != null) + return this.getDefaultState().with(HORIZONTAL_AXIS, preferredAxis); + return this.getDefaultState().with(HORIZONTAL_AXIS, context.getPlacementHorizontalFacing().rotateY().getAxis()); + } + + public Axis getPreferredHorizontalAxis(BlockItemUseContext context) { + Direction prefferedSide = null; + for (Direction side : Direction.values()) { + if (side.getAxis().isVertical()) + continue; + BlockState blockState = context.getWorld().getBlockState(context.getPos().offset(side)); + if (blockState.getBlock() instanceof IRotate) { + if (((IRotate) blockState.getBlock()).hasShaftTowards(context.getWorld(), context.getPos().offset(side), + blockState, side.getOpposite())) + if (prefferedSide != null && prefferedSide.getAxis() != side.getAxis()) { + prefferedSide = null; + break; + } else { + prefferedSide = side; + } + } + } + return prefferedSide == null ? null : prefferedSide.getAxis(); + } + + @Override + public Axis getRotationAxis(BlockState state) { + return state.get(HORIZONTAL_AXIS); + } + + @Override + public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { + return face.getAxis() == state.get(HORIZONTAL_AXIS); + } + + @Override + public ActionResultType onWrenched(BlockState state, ItemUseContext context) { + Direction facing = context.getFace(); + if (facing.getAxis().isVertical()) + return ActionResultType.PASS; + World world = context.getWorld(); + if (facing.getAxis() == state.get(HORIZONTAL_AXIS)) + return ActionResultType.PASS; + if (!world.isRemote) { + BlockPos pos = context.getPos(); + KineticTileEntity tileEntity = (KineticTileEntity) world.getTileEntity(pos); + if (tileEntity.hasNetwork()) + tileEntity.getNetwork().remove(tileEntity); + RotationPropagator.handleRemoved(world, pos, tileEntity); + tileEntity.removeSource(); + world.setBlockState(pos, state.cycle(HORIZONTAL_AXIS), 3); + tileEntity.attachKinetics(); + } + return ActionResultType.SUCCESS; + } + + @Override + public BlockState rotate(BlockState state, Rotation rot) { + Axis axis = state.get(HORIZONTAL_AXIS); + return state.with(HORIZONTAL_AXIS, + rot.rotate(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis)).getAxis()); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirrorIn) { + return state; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java index ce6089984..c82a2aba9 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java @@ -16,6 +16,8 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { @Override public void startMoving(MovementContext context) { + if (context.world.isRemote) + return; context.data.putInt("BreakerId", -BlockBreakingKineticTileEntity.NEXT_BREAKER_ID.incrementAndGet()); } @@ -40,6 +42,8 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { @Override public void stopMoving(MovementContext context) { CompoundNBT data = context.data; + if (context.world.isRemote) + return; if (!data.contains("BreakingPos")) return; @@ -58,6 +62,8 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { @Override public void tick(MovementContext context) { CompoundNBT data = context.data; + if (context.world.isRemote) + return; if (!data.contains("BreakingPos")) return; if (context.relativeMotion.equals(Vec3d.ZERO)) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/clock/CuckooClockTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/clock/CuckooClockTileEntity.java index 1039fe575..620c40b0b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/clock/CuckooClockTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/clock/CuckooClockTileEntity.java @@ -1,5 +1,9 @@ package com.simibubi.create.modules.contraptions.components.clock; +import static com.simibubi.create.foundation.utility.AngleHelper.deg; +import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngleDiff; +import static com.simibubi.create.foundation.utility.AngleHelper.rad; + import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; @@ -20,7 +24,7 @@ import net.minecraft.world.Explosion; public class CuckooClockTileEntity extends KineticTileEntity { public static DamageSource CUCKOO_SURPRISE = new DamageSource("create.cuckoo_clock_explosion").setExplosion(); - + public InterpolatedChasingValue hourHand = new InterpolatedChasingValue().withSpeed(.2f); public InterpolatedChasingValue minuteHand = new InterpolatedChasingValue().withSpeed(.2f); public InterpolatedValue animationProgress = new InterpolatedValue(); @@ -69,22 +73,23 @@ public class CuckooClockTileEntity extends KineticTileEntity { if (!world.isRemote) { if (animationType == null) { - if (hours == 12 && minutes < 5) + if (hours == 12 && minutes < 5) startAnimation(Animation.PIG); - if (hours == 18 && minutes < 36 && minutes > 31) + if (hours == 18 && minutes < 36 && minutes > 31) startAnimation(Animation.CREEPER); } else { float value = animationProgress.value; animationProgress.set(value + 1); if (value > 100) animationType = null; - + if (animationType == Animation.SURPRISE && animationProgress.value == 50) { Vec3d center = VecHelper.getCenterOf(pos); world.destroyBlock(pos, false); - world.createExplosion(null, CUCKOO_SURPRISE, center.x, center.y, center.z, 3, false, Explosion.Mode.BREAK); + world.createExplosion(null, CUCKOO_SURPRISE, center.x, center.y, center.z, 3, false, + Explosion.Mode.BREAK); } - + } } @@ -150,21 +155,11 @@ public class CuckooClockTileEntity extends KineticTileEntity { } public void moveHands(int hours, int minutes) { - float hourTarget = (float) (2 * Math.PI / 12 * (hours % 12)); - float minuteTarget = (float) (2 * Math.PI / 60 * minutes); + float hourTarget = (float) (360 / 12 * (hours % 12)); + float minuteTarget = (float) (360 / 60 * minutes); - hourHand.target(hourTarget); - minuteHand.target(minuteTarget); - - if (minuteTarget - minuteHand.value < 0) { - minuteHand.value = (float) (minuteHand.value - Math.PI * 2); - minuteHand.lastValue = minuteHand.value; - } - - if (hourTarget - hourHand.value < 0) { - hourHand.value = (float) (hourHand.value - Math.PI * 2); - hourHand.lastValue = hourHand.value; - } + hourHand.target(hourHand.value + rad(getShortestAngleDiff(deg(hourHand.value), hourTarget))); + minuteHand.target(minuteHand.value + rad(getShortestAngleDiff(deg(minuteHand.value), minuteTarget))); hourHand.tick(); minuteHand.tick(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index 4ebda5c84..bbdd0f0ba 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.MutablePair; @@ -22,13 +23,10 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.NBTHelper; -import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.LinearChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.RadialChassisBlock; -import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption; -import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonContraption; import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import net.minecraft.block.Block; @@ -57,6 +55,8 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper; public class Contraption { + protected static Map> deserializers = new HashMap<>(); + public Map blocks; public Map storage; public List> actors; @@ -69,6 +69,10 @@ public class Contraption { protected Direction cachedColliderDirection; protected BlockPos anchor; + protected static void register(String name, Supplier factory) { + deserializers.put(name, factory); + } + public Contraption() { blocks = new HashMap<>(); storage = new HashMap<>(); @@ -168,7 +172,7 @@ public class Contraption { return true; } - private boolean moveBlock(World world, BlockPos pos, Direction direction, List frontier, + protected boolean moveBlock(World world, BlockPos pos, Direction direction, List frontier, Set visited) { visited.add(pos); frontier.remove(pos); @@ -478,12 +482,8 @@ public class Contraption { public static Contraption fromNBT(World world, CompoundNBT nbt) { String type = nbt.getString("Type"); Contraption contraption = new Contraption(); - if (type.equals("Piston")) - contraption = new PistonContraption(); - if (type.equals("Mounted")) - contraption = new MountedContraption(); - if (type.equals("Bearing")) - contraption = new BearingContraption(); + if (deserializers.containsKey(type)) + contraption = deserializers.get(type).get(); contraption.readNBT(world, nbt); return contraption; } @@ -525,14 +525,7 @@ public class Contraption { public CompoundNBT writeNBT() { CompoundNBT nbt = new CompoundNBT(); - - if (this instanceof PistonContraption) - nbt.putString("Type", "Piston"); - if (this instanceof MountedContraption) - nbt.putString("Type", "Mounted"); - if (this instanceof BearingContraption) - nbt.putString("Type", "Bearing"); - + nbt.putString("Type", getType()); ListNBT blocksNBT = new ListNBT(); for (BlockInfo block : this.blocks.values()) { CompoundNBT c = new CompoundNBT(); @@ -676,4 +669,8 @@ public class Contraption { return ((IPortableBlock) block).getMovementBehaviour(); } + protected String getType() { + return "Contraption"; + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index 63c9fa456..6aa24a521 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -1,5 +1,8 @@ package com.simibubi.create.modules.contraptions.components.contraptions; +import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp; +import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngleDiff; + import org.apache.commons.lang3.tuple.MutablePair; import com.simibubi.create.AllEntities; @@ -38,6 +41,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected BlockPos controllerPos; protected IControlContraption controllerTE; protected Vec3d motionBeforeStall; + protected boolean stationary; private static final DataParameter STALLED = EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN); @@ -57,21 +61,27 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public ContraptionEntity(EntityType entityTypeIn, World worldIn) { super(entityTypeIn, worldIn); motionBeforeStall = Vec3d.ZERO; + stationary = entityTypeIn == AllEntities.STATIONARY_CONTRAPTION.type; } - protected ContraptionEntity(World world) { - this(AllEntities.CONTRAPTION.type, world); - } - - public ContraptionEntity(World world, Contraption contraption, float initialAngle) { - this(world); - this.contraption = contraption; - this.initialAngle = initialAngle; - this.prevYaw = initialAngle; - this.yaw = initialAngle; - this.targetYaw = initialAngle; + public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) { + ContraptionEntity entity = new ContraptionEntity(AllEntities.CONTRAPTION.type, world); + entity.contraption = contraption; + entity.initialAngle = initialAngle; + entity.prevYaw = initialAngle; + entity.yaw = initialAngle; + entity.targetYaw = initialAngle; if (contraption != null) contraption.gatherStoredItems(); + return entity; + } + + public static ContraptionEntity createStationary(World world, Contraption contraption) { + ContraptionEntity entity = new ContraptionEntity(AllEntities.STATIONARY_CONTRAPTION.type, world); + entity.contraption = contraption; + if (contraption != null) + contraption.gatherStoredItems(); + return entity; } public ContraptionEntity controlledBy(T controller) { @@ -131,6 +141,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return; } + if (getMotion().length() > 1 / 4098f) + move(getMotion().x, getMotion().y, getMotion().z); + prevYaw = yaw; prevPitch = pitch; prevRoll = roll; @@ -160,7 +173,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch); actorPosition = actorPosition.add(rotationOffset).add(posX, posY, posZ); - boolean newPosVisited = context.position == null; + boolean newPosVisited = false; BlockPos gridPosition = new BlockPos(actorPosition); if (!stalledPreviously) { @@ -170,7 +183,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD Vec3d relativeMotion = context.motion; relativeMotion = VecHelper.rotate(relativeMotion, -angleRoll, -angleYaw, -anglePitch); context.relativeMotion = relativeMotion; - newPosVisited = !new BlockPos(previousPosition).equals(gridPosition); + newPosVisited = !new BlockPos(previousPosition).equals(gridPosition) + || context.relativeMotion.length() > 0 && context.firstMovement; } } @@ -178,16 +192,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD context.position = actorPosition; if (actor.isActive(context)) { - if (newPosVisited && !context.stall) + if (newPosVisited && !context.stall) { actor.visitNewPosition(context, gridPosition); + context.firstMovement = false; + } actor.tick(context); contraption.stalled |= context.stall; } - } if (!world.isRemote) { if (!stalledPreviously && contraption.stalled) { + setMotion(Vec3d.ZERO); if (controllerTE != null) controllerTE.onStall(); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), @@ -240,6 +256,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD this.posX = x; this.posY = y; this.posZ = z; + if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld) ((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving. if (contraption != null) { @@ -277,16 +294,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return partialTicks == 1.0F ? roll : angleLerp(partialTicks, prevRoll, roll); } - private float angleLerp(float pct, float current, float target) { - return current + getShortestAngleDiff(current, target) * pct; - } - - private float getShortestAngleDiff(double current, double target) { - current = current % 360; - target = target % 360; - return (float) (((((target - current) % 360) + 540) % 360) - 180); - } - public static EntityType.Builder build(EntityType.Builder builder) { @SuppressWarnings("unchecked") EntityType.Builder entityBuilder = (EntityType.Builder) builder; @@ -367,6 +374,17 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return dataManager.get(STALLED); } + @OnlyIn(Dist.CLIENT) + @Override + public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, + int posRotationIncrements, boolean teleport) { + // Stationary Anchors are responsible for keeping position and motion in sync + // themselves. + if (stationary) + return; + super.setPositionAndRotationDirect(x, y, z, yaw, pitch, posRotationIncrements, teleport); + } + @OnlyIn(Dist.CLIENT) static void handleStallPacket(ContraptionStallPacket packet) { Entity entity = Minecraft.getInstance().world.getEntityByID(packet.entityID); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MovementContext.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MovementContext.java index 1e7e81e0c..ae8bbe420 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MovementContext.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MovementContext.java @@ -20,6 +20,7 @@ public class MovementContext { public CompoundNBT tileData; public boolean stall; + public boolean firstMovement; public CompoundNBT data; public Contraption contraption; public Object temporaryData; @@ -28,7 +29,8 @@ public class MovementContext { this.world = world; this.state = info.state; this.tileData = info.nbt; - + + firstMovement = true; motion = Vec3d.ZERO; relativeMotion = Vec3d.ZERO; rotation = Vec3d.ZERO; @@ -55,6 +57,7 @@ public class MovementContext { if (nbt.contains("Position")) context.position = VecHelper.readNBT(nbt.getList("Position", NBT.TAG_DOUBLE)); context.stall = nbt.getBoolean("Stall"); + context.firstMovement = nbt.getBoolean("FirstMovement"); context.data = nbt.getCompound("Data"); return context; } @@ -66,6 +69,7 @@ public class MovementContext { if (position != null) nbt.put("Position", VecHelper.writeNBT(position)); nbt.putBoolean("Stall", stall); + nbt.putBoolean("FirstMovement", firstMovement); nbt.put("Data", data); return nbt; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingBlock.java new file mode 100644 index 000000000..059779c11 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingBlock.java @@ -0,0 +1,43 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.bearing; + +import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldReader; + +public abstract class BearingBlock extends DirectionalKineticBlock { + + public BearingBlock() { + super(Properties.from(Blocks.PISTON)); + } + + @Override + public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { + return face == state.get(FACING).getOpposite(); + } + + @Override + protected boolean hasStaticPart() { + return true; + } + + @Override + protected boolean turnBackOnWrenched() { + return true; + } + + @Override + public Axis getRotationAxis(BlockState state) { + return state.get(FACING).getAxis(); + } + + @Override + public boolean showCapacityWithAnnotation() { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java index d6aa37a11..3107f3f70 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java @@ -13,10 +13,21 @@ import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; public class BearingContraption extends Contraption { - + protected int sailBlocks; protected Direction facing; + private static String type = "Bearing"; + + static { + register(type, BearingContraption::new); + } + + @Override + protected String getType() { + return type; + } + public static BearingContraption assembleBearingAt(World world, BlockPos pos, Direction direction) { if (isFrozen()) return null; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java similarity index 81% rename from src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java index 1a804d37f..d42d7c165 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java @@ -11,21 +11,21 @@ import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; -public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRenderer { +public class BearingTileEntityRenderer extends KineticTileEntityRenderer { @Override public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer) { super.renderFast(te, x, y, z, partialTicks, destroyStage, buffer); - MechanicalBearingTileEntity bearingTe = (MechanicalBearingTileEntity) te; + IBearingTileEntity bearingTe = (IBearingTileEntity) te; final Direction facing = te.getBlockState().get(BlockStateProperties.FACING); SuperByteBuffer superBuffer = AllBlockPartials.MECHANICAL_BEARING_TOP.renderOn(te.getBlockState()); superBuffer.rotateCentered(Axis.X, AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing))); if (facing.getAxis().isHorizontal()) superBuffer.rotateCentered(Axis.Y, AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite()))); float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks - 1); - kineticRotationTransform(superBuffer, bearingTe, facing.getAxis(), (float) (interpolatedAngle / 180 * Math.PI), + kineticRotationTransform(superBuffer, te, facing.getAxis(), (float) (interpolatedAngle / 180 * Math.PI), getWorld()); superBuffer.translate(x, y, z).renderInto(buffer); } @@ -33,7 +33,7 @@ public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRender @Override protected SuperByteBuffer getRotatedModel(KineticTileEntity te) { return AllBlockPartials.SHAFT_HALF.renderOnDirectional(te.getBlockState(), - te.getBlockState().get(MechanicalBearingBlock.FACING).getOpposite()); + te.getBlockState().get(BearingBlock.FACING).getOpposite()); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java new file mode 100644 index 000000000..fa4694369 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingBlock.java @@ -0,0 +1,14 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.bearing; + +import net.minecraft.block.BlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockReader; + +public class ClockworkBearingBlock extends BearingBlock { + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new ClockworkBearingTileEntity(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java new file mode 100644 index 000000000..e6a264710 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java @@ -0,0 +1,266 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.bearing; + +import org.apache.commons.lang3.tuple.Pair; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.ServerSpeedProvider; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkContraption.HandType; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity { + + protected ContraptionEntity hourHand; + protected ContraptionEntity minuteHand; + protected float hourAngle; + protected float minuteAngle; + protected float clientHourAngleDiff; + protected float clientMinuteAngleDiff; + + protected boolean running; + protected boolean assembleNextTick; + + public ClockworkBearingTileEntity() { + super(AllTileEntities.CLOCKWORK_BEARING.type); + setLazyTickRate(3); + } + + @Override + public void tick() { + super.tick(); + + if (world.isRemote) { + clientMinuteAngleDiff /= 2; + clientHourAngleDiff /= 2; + } + + if (running && Contraption.isFrozen()) + disassembleConstruct(); + + if (!world.isRemote && assembleNextTick) { + assembleNextTick = false; + if (running) { + boolean canDisassemble = true; + if (speed == 0 && (canDisassemble || hourHand == null || hourHand.getContraption().blocks.isEmpty())) { + if (hourHand != null) + hourHand.getContraption().stop(world); + if (minuteHand != null) + minuteHand.getContraption().stop(world); + disassembleConstruct(); + } + return; + } else { + assembleConstruct(); + } + return; + } + + if (!running) + return; + + if (!(hourHand != null && hourHand.isStalled())) { + float newAngle = hourAngle + getHourArmSpeed(); + hourAngle = (float) (newAngle % 360); + } + + if (!(minuteHand != null && minuteHand.isStalled())) { + float newAngle = minuteAngle + getMinuteArmSpeed(); + minuteAngle = (float) (newAngle % 360); + } + + applyRotations(); + } + + protected void applyRotations() { + Axis axis = getBlockState().get(BlockStateProperties.FACING).getAxis(); + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + Vec3d directionVec = new Vec3d(direction.getDirectionVec()); + if (hourHand != null) { + Vec3d vec = new Vec3d(1, 1, 1).scale(hourAngle).mul(directionVec); + hourHand.rotateTo(vec.x, vec.y, vec.z); + } + if (minuteHand != null) { + Vec3d vec = new Vec3d(1, 1, 1).scale(minuteAngle).mul(directionVec); + minuteHand.rotateTo(vec.x, vec.y, vec.z); + } + } + + @Override + public void lazyTick() { + super.lazyTick(); + if (hourHand != null && !world.isRemote) + sendData(); + } + + public float getHourArmSpeed() { + float speed = getAngularSpeed() / 2f + clientHourAngleDiff / 3f; + + if (speed != 0) { + int dayTime = (int) (world.getDayTime() % 24000); + int hours = (dayTime / 1000 + 6) % 24; + float hourTarget = (float) (-360 / 12f * (hours % 12)); + speed = Math.max(speed, AngleHelper.getShortestAngleDiff(hourAngle, hourTarget)); + } + + return speed; + } + + public float getMinuteArmSpeed() { + float speed = getAngularSpeed() + clientMinuteAngleDiff / 3f; + + if (speed != 0) { + int dayTime = (int) (world.getDayTime() % 24000); + int minutes = (dayTime % 1000) * 60 / 1000; + float hourTarget = (float) (-360 / 60f * (minutes)); + speed = Math.max(speed, AngleHelper.getShortestAngleDiff(minuteAngle, hourTarget)); + } + + return speed; + } + + public float getAngularSpeed() { + float speed = -Math.abs(getSpeed() * 3 / 10f); + if (world.isRemote) + speed *= ServerSpeedProvider.get(); + return speed; + } + + public void assembleConstruct() { + Direction direction = getBlockState().get(BlockStateProperties.FACING); + + // Collect Construct + Pair contraption = + ClockworkContraption.assembleClockworkAt(world, pos, direction); + if (contraption == null) + return; + if (contraption.getLeft() == null) + return; + BlockPos anchor = pos.offset(direction); + + contraption.getLeft().removeBlocksFromWorld(world, BlockPos.ZERO); + hourHand = ContraptionEntity.createStationary(world, contraption.getLeft()).controlledBy(this); + hourHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); + world.addEntity(hourHand); + + if (contraption.getRight() != null) { + anchor = pos.offset(direction, contraption.getRight().offset + 1); + contraption.getRight().removeBlocksFromWorld(world, BlockPos.ZERO); + minuteHand = ContraptionEntity.createStationary(world, contraption.getRight()).controlledBy(this); + minuteHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); + world.addEntity(minuteHand); + } + + // Run + running = true; + hourAngle = 0; + minuteAngle = 0; + sendData(); + } + + public void disassembleConstruct() { + if (!running) + return; + if (hourHand != null) + hourHand.disassemble(); + if (minuteHand != null) + minuteHand.disassemble(); + + hourHand = null; + minuteHand = null; + running = false; + hourAngle = 0; + minuteAngle = 0; + sendData(); + } + + @Override + public void attach(ContraptionEntity contraption) { + if (contraption.getContraption() instanceof ClockworkContraption) { + ClockworkContraption cc = (ClockworkContraption) contraption.getContraption(); + markDirty(); + Direction facing = getBlockState().get(BlockStateProperties.FACING); + BlockPos anchor = pos.offset(facing, cc.offset + 1); + if (cc.handType == HandType.HOUR) { + this.hourHand = contraption; + hourHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); + } else { + this.minuteHand = contraption; + minuteHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); + } + if (!world.isRemote) + sendData(); + } + } + + @Override + public CompoundNBT write(CompoundNBT tag) { + tag.putBoolean("Running", running); + tag.putFloat("HourAngle", hourAngle); + tag.putFloat("MinuteAngle", minuteAngle); + return super.write(tag); + } + + @Override + public void read(CompoundNBT tag) { + running = tag.getBoolean("Running"); + hourAngle = tag.getFloat("HourAngle"); + minuteAngle = tag.getFloat("MinuteAngle"); + super.read(tag); + } + + @Override + public void readClientUpdate(CompoundNBT tag) { + float hourAngleBefore = hourAngle; + float minuteAngleBefore = minuteAngle; + super.readClientUpdate(tag); + if (running) { + clientHourAngleDiff = AngleHelper.getShortestAngleDiff(hourAngleBefore, hourAngle); + clientMinuteAngleDiff = AngleHelper.getShortestAngleDiff(minuteAngleBefore, minuteAngle); + hourAngle = hourAngleBefore; + minuteAngle = minuteAngleBefore; + } + } + + @Override + public void onSpeedChanged(float prevSpeed) { + super.onSpeedChanged(prevSpeed); + assembleNextTick = true; + } + + @Override + public boolean isValid() { + return !isRemoved(); + } + + @Override + public float getInterpolatedAngle(float partialTicks) { + if (hourHand != null && hourHand.isStalled()) + partialTicks = 0; + return MathHelper.lerp(partialTicks, hourAngle, hourAngle + getHourArmSpeed()); + } + + @Override + public void onStall() { + if (!world.isRemote) + sendData(); + } + + @Override + public void remove() { + if (!world.isRemote) + disassembleConstruct(); + super.remove(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java new file mode 100644 index 000000000..098e1213d --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java @@ -0,0 +1,122 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.bearing; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiPredicate; + +import org.apache.commons.lang3.tuple.Pair; + +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; + +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class ClockworkContraption extends Contraption { + + protected Direction facing; + public HandType handType; + public int offset; + private Set ignoreBlocks = new HashSet<>(); + + private static String type = "Clockwork"; + + static { + register(type, ClockworkContraption::new); + } + + @Override + protected String getType() { + return type; + } + + private void ignoreBlocks(Set blocks, BlockPos anchor) { + for (BlockPos blockPos : blocks) + ignoreBlocks.add(anchor.add(blockPos)); + } + + public static Pair assembleClockworkAt(World world, BlockPos pos, + Direction direction) { + if (isFrozen()) + return null; + + int hourArmBlocks = 0; + + ClockworkContraption hourArm = new ClockworkContraption(); + ClockworkContraption minuteArm = null; + + hourArm.facing = direction; + hourArm.handType = HandType.HOUR; + if (!hourArm.searchMovedStructure(world, pos, direction)) + return null; + for (int i = 0; i < 16; i++) { + BlockPos offsetPos = BlockPos.ZERO.offset(direction, i); + if (hourArm.blocks.containsKey(offsetPos)) + continue; + hourArmBlocks = i; + break; + } + + if (hourArmBlocks > 0) { + minuteArm = new ClockworkContraption(); + minuteArm.facing = direction; + minuteArm.handType = HandType.MINUTE; + minuteArm.offset = hourArmBlocks; + minuteArm.ignoreBlocks(hourArm.blocks.keySet(), hourArm.anchor); + if (!minuteArm.searchMovedStructure(world, pos, direction)) + return null; + if (minuteArm.blocks.isEmpty()) + minuteArm = null; + } + + hourArm.initActors(world); + if (minuteArm != null) + minuteArm.initActors(world); + return Pair.of(hourArm, minuteArm); + } + + @Override + public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { + return super.searchMovedStructure(world, pos.offset(direction, offset + 1), direction); + } + + @Override + public void disassemble(World world, BlockPos offset, float yaw, float pitch, + BiPredicate customPlacement) { + super.disassemble(world, offset, yaw, pitch, customPlacement); + } + + @Override + protected boolean moveBlock(World world, BlockPos pos, Direction direction, List frontier, + Set visited) { + if (ignoreBlocks.contains(pos)) + return true; + return super.moveBlock(world, pos, direction, frontier, visited); + } + + @Override + public CompoundNBT writeNBT() { + CompoundNBT tag = super.writeNBT(); + tag.putInt("facing", facing.getIndex()); + tag.putInt("offset", offset); + tag.putString("HandType", NBTHelper.writeEnum(handType)); + return tag; + } + + @Override + public void readNBT(World world, CompoundNBT tag) { + facing = Direction.byIndex(tag.getInt("Facing")); + handType = NBTHelper.readEnum(tag.getString("HandType"), HandType.class); + offset = tag.getInt("offset"); + super.readNBT(world, tag); + } + + public static enum HandType { + HOUR, MINUTE + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/IBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/IBearingTileEntity.java new file mode 100644 index 000000000..97b3e060e --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/IBearingTileEntity.java @@ -0,0 +1,9 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.bearing; + +import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption; + +public interface IBearingTileEntity extends IControlContraption { + + float getInterpolatedAngle(float partialTicks); + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java index d5161d6e3..a62d865d2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingBlock.java @@ -1,25 +1,15 @@ package com.simibubi.create.modules.contraptions.components.contraptions.bearing; import com.simibubi.create.foundation.block.IWithTileEntity; -import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorldReader; import net.minecraft.world.World; -public class MechanicalBearingBlock extends DirectionalKineticBlock - implements IWithTileEntity { - - public MechanicalBearingBlock() { - super(Properties.from(Blocks.PISTON)); - } +public class MechanicalBearingBlock extends BearingBlock implements IWithTileEntity { @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { @@ -35,29 +25,4 @@ public class MechanicalBearingBlock extends DirectionalKineticBlock withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged); } - @Override - public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { - return face == state.get(FACING).getOpposite(); - } - - @Override - protected boolean hasStaticPart() { - return true; - } - - @Override - protected boolean turnBackOnWrenched() { - return true; - } - - @Override - public Axis getRotationAxis(BlockState state) { - return state.get(FACING).getAxis(); - } - - @Override - public boolean showCapacityWithAnnotation() { - return true; - } - } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java index ffdeb7048..3c175d264 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java @@ -1,11 +1,11 @@ package com.simibubi.create.modules.contraptions.components.contraptions.bearing; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; -import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; @@ -16,14 +16,13 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IControlContraption { +public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity { + protected boolean isWindmill; protected ContraptionEntity movedContraption; protected float angle; protected boolean running; protected boolean assembleNextTick; - protected boolean isWindmill; - protected float clientAngleDiff; public MechanicalBearingTileEntity() { @@ -99,12 +98,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void readClientUpdate(CompoundNBT tag) { float angleBefore = angle; super.readClientUpdate(tag); - clientAngleDiff = angle - angleBefore; - if (Math.abs(clientAngleDiff) > 20) - clientAngleDiff = 0; + clientAngleDiff = AngleHelper.getShortestAngleDiff(angleBefore, angle); angle = angleBefore; } + @Override public float getInterpolatedAngle(float partialTicks) { if (movedContraption != null && movedContraption.isStalled()) partialTicks = 0; @@ -136,7 +134,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp if (isWindmill && contraption.getSailBlocks() == 0) return; contraption.removeBlocksFromWorld(world, BlockPos.ZERO); - movedContraption = new ContraptionEntity(world, contraption, 0).controlledBy(this); + movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this); BlockPos anchor = pos.offset(direction); movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); world.addEntity(movedContraption); @@ -152,8 +150,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void disassembleConstruct() { if (!running) return; - - movedContraption.disassemble(); + if (movedContraption != null) + movedContraption.disassemble(); + movedContraption = null; running = false; angle = 0; @@ -209,7 +208,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp sendData(); } - private void applyRotation() { + protected void applyRotation() { if (movedContraption != null) { Axis axis = getBlockState().get(BlockStateProperties.FACING).getAxis(); Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index 811c0ea7f..fa74c19e8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -30,8 +30,8 @@ import net.minecraft.world.World; public class CartAssemblerBlock extends AbstractRailBlock { - public static IProperty RAIL_SHAPE = EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, - RailShape.NORTH_SOUTH); + public static IProperty RAIL_SHAPE = + EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH); public static BooleanProperty POWERED = BlockStateProperties.POWERED; public CartAssemblerBlock() { @@ -75,8 +75,8 @@ public class CartAssemblerBlock extends AbstractRailBlock { Contraption contraption = MountedContraption.assembleMinecart(world, pos, cart); if (contraption == null) return; - ContraptionEntity entity = new ContraptionEntity(world, contraption, - ContraptionEntity.yawFromVector(cart.getMotion())); + float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion()); + ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle); entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); world.addEntity(entity); entity.startRiding(cart); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index 27c6647ad..ca873a4ea 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -25,6 +25,17 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; public class MountedContraption extends Contraption { + private static String type = "Mounted"; + + static { + register(type, MountedContraption::new); + } + + @Override + protected String getType() { + return type; + } + public static Contraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) { if (isFrozen()) return null; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java new file mode 100644 index 000000000..7a019dc43 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java @@ -0,0 +1,201 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.piston; + +import com.simibubi.create.foundation.utility.ServerSpeedProvider; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + + +public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption { + public float offset; + public boolean running; + protected boolean assembleNextTick; + public ContraptionEntity movedContraption; + protected boolean forceMove; + + // Custom position sync + protected float clientOffsetDiff; + + public LinearActuatorTileEntity(TileEntityType typeIn) { + super(typeIn); + setLazyTickRate(3); + } + + @Override + public void tick() { + super.tick(); + boolean contraptionPresent = movedContraption != null; + + if (contraptionPresent) + if (!movedContraption.isAlive()) + movedContraption = null; + + if (world.isRemote) + clientOffsetDiff *= .75f; + + if (!world.isRemote && assembleNextTick) { + assembleNextTick = false; + if (running) { + if (getSpeed() == 0) + disassembleConstruct(); + else + sendData(); + return; + } + assembleConstruct(); + return; + } + + if (!running) + return; + + contraptionPresent = movedContraption != null; + float movementSpeed = getMovementSpeed(); + float newOffset = offset + movementSpeed; + if ((int) newOffset != (int) offset) + visitNewPosition(); + + if (!contraptionPresent || !movedContraption.isStalled()) + offset = newOffset; + + if (contraptionPresent) + applyContraptionMotion(); + + int extensionRange = getExtensionRange(); + if (offset <= 0 || offset >= extensionRange) { + offset = offset <= 0 ? 0 : extensionRange; + if (!world.isRemote) + disassembleConstruct(); + return; + } + } + + @Override + public void lazyTick() { + super.lazyTick(); + if (movedContraption != null && !world.isRemote) + sendData(); + } + + protected int getGridOffset(float offset) { + return MathHelper.clamp((int) (offset + .5f), 0, getExtensionRange()); + } + + public float getInterpolatedOffset(float partialTicks) { + float interpolatedOffset = + MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0, getExtensionRange()); + return interpolatedOffset; + } + + @Override + public void onSpeedChanged(float prevSpeed) { + super.onSpeedChanged(prevSpeed); + assembleNextTick = true; + } + + @Override + public void remove() { + this.removed = true; + if (!world.isRemote) + disassembleConstruct(); + super.remove(); + } + + @Override + public CompoundNBT write(CompoundNBT tag) { + tag.putBoolean("Running", running); + tag.putFloat("Offset", offset); + return super.write(tag); + } + + @Override + public CompoundNBT writeToClient(CompoundNBT compound) { + if (forceMove) { + compound.putBoolean("ForceMovement", forceMove); + forceMove = false; + } + return super.writeToClient(compound); + } + + @Override + public void read(CompoundNBT tag) { + running = tag.getBoolean("Running"); + offset = tag.getFloat("Offset"); + super.read(tag); + } + + @Override + public void readClientUpdate(CompoundNBT tag) { + float offsetBefore = offset; + super.readClientUpdate(tag); + if (running) { + clientOffsetDiff = offset - offsetBefore; + offset = offsetBefore; + } + + if (tag.contains("ForceMovement")) + if (movedContraption != null) + applyContraptionPosition(); + } + + protected abstract void assembleConstruct(); + + protected abstract void disassembleConstruct(); + + protected abstract int getExtensionRange(); + + protected abstract void visitNewPosition(); + + protected abstract Vec3d toMotionVector(float speed); + + protected abstract Vec3d toPosition(float offset); + + protected void applyContraptionMotion() { + if (movedContraption.isStalled()) + movedContraption.setMotion(Vec3d.ZERO); + else + movedContraption.setMotion(getMotionVector()); + } + + protected void applyContraptionPosition() { + Vec3d vec = toPosition(offset); + movedContraption.setPosition(vec.x, vec.y, vec.z); + } + + public float getMovementSpeed() { + float movementSpeed = getSpeed() / 512f + clientOffsetDiff / 2f; + if (world.isRemote) + movementSpeed *= ServerSpeedProvider.get(); + return movementSpeed; + } + + public Vec3d getMotionVector() { + return toMotionVector(getMovementSpeed()); + } + + @Override + public void onStall() { + if (!world.isRemote) { + forceMove = true; + sendData(); + } + } + + @Override + public boolean isValid() { + return !isRemoved(); + } + + @Override + public void attach(ContraptionEntity contraption) { + this.movedContraption = contraption; + if (!world.isRemote) + sendData(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java index 39d766e9e..dd45261cc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java @@ -2,10 +2,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions.piston; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.utility.ServerSpeedProvider; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; -import com.simibubi.create.modules.contraptions.components.contraptions.IControlContraption; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import net.minecraft.nbt.CompoundNBT; @@ -13,17 +10,11 @@ import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -public class MechanicalPistonTileEntity extends KineticTileEntity implements IControlContraption { +public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { - protected float offset; - protected boolean running; - protected boolean assembleNextTick; protected boolean hadCollisionWithOtherPiston; - - protected ContraptionEntity movedContraption; protected int extensionLength; public MechanicalPistonTileEntity() { @@ -31,35 +22,18 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo } @Override - public void onSpeedChanged(float prevSpeed) { - super.onSpeedChanged(prevSpeed); - assembleNextTick = true; - } - - @Override - public void remove() { - this.removed = true; - if (!world.isRemote) - disassembleConstruct(); - super.remove(); + public void read(CompoundNBT tag) { + extensionLength = tag.getInt("ExtensionLength"); + super.read(tag); } @Override public CompoundNBT write(CompoundNBT tag) { - tag.putBoolean("Running", running); - tag.putFloat("Offset", offset); tag.putInt("ExtensionLength", extensionLength); return super.write(tag); } @Override - public void read(CompoundNBT tag) { - running = tag.getBoolean("Running"); - offset = tag.getFloat("Offset"); - extensionLength = tag.getInt("ExtensionLength"); - super.read(tag); - } - public void assembleConstruct() { Direction direction = getBlockState().get(BlockStateProperties.FACING); @@ -82,19 +56,22 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo BlockPos startPos = BlockPos.ZERO.offset(direction, contraption.initialExtensionProgress); contraption.removeBlocksFromWorld(world, startPos); - movedContraption = new ContraptionEntity(getWorld(), contraption, 0).controlledBy(this); - moveContraption(); + movedContraption = ContraptionEntity.createStationary(getWorld(), contraption).controlledBy(this); + applyContraptionPosition(); + forceMove = true; world.addEntity(movedContraption); } + @Override public void disassembleConstruct() { if (!running) return; - if (!removed) getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3); - if (movedContraption != null) + if (movedContraption != null) { + applyContraptionPosition(); movedContraption.disassemble(); + } running = false; movedContraption = null; sendData(); @@ -104,58 +81,31 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo } @Override - public void tick() { - super.tick(); - - if (movedContraption != null && movedContraption.isStalled()) - return; - - if (!world.isRemote && assembleNextTick) { - assembleNextTick = false; - if (running) { - if (getSpeed() == 0) - disassembleConstruct(); - else - sendData(); - return; - } - assembleConstruct(); - return; - } - - if (!running) - return; - - float movementSpeed = getMovementSpeed(); - if (world.isRemote) - movementSpeed *= ServerSpeedProvider.get(); - float newOffset = offset + movementSpeed; - - if (movedContraption == null) - return; - if (!world.isRemote && getModulatedOffset(newOffset) != getModulatedOffset(offset)) { - offset = newOffset; - sendData(); - } - - offset = newOffset; - moveContraption(); - - if (offset <= 0 || offset >= extensionLength) { - offset = offset <= 0 ? 0 : extensionLength; - if (!world.isRemote) - disassembleConstruct(); - return; - } + public float getMovementSpeed() { + Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING); + int movementModifier = + pistonDirection.getAxisDirection().getOffset() * (pistonDirection.getAxis() == Axis.Z ? -1 : 1); + return super.getMovementSpeed() * -movementModifier; } - public void moveContraption() { - if (movedContraption != null) { - Vec3d constructOffset = getConstructOffset(0.5f); - Vec3d vec = constructOffset.add(new Vec3d(movedContraption.getContraption().getAnchor())); - movedContraption.move(vec.x - movedContraption.posX, vec.y - movedContraption.posY, - vec.z - movedContraption.posZ); - } + @Override + protected int getExtensionRange() { + return extensionLength; + } + + @Override + protected void visitNewPosition() { + } + + @Override + protected Vec3d toMotionVector(float speed) { + return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(speed); + } + + @Override + protected Vec3d toPosition(float offset) { + Vec3d position = new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(offset); + return position.add(new Vec3d(movedContraption.getContraption().getAnchor())); } // private boolean hasBlockCollisions(float newOffset) { @@ -236,41 +186,4 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ICo // return false; // } - private int getModulatedOffset(float offset) { - return MathHelper.clamp((int) (offset + .5f), 0, extensionLength); - } - - public float getMovementSpeed() { - Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING); - int movementModifier = - pistonDirection.getAxisDirection().getOffset() * (pistonDirection.getAxis() == Axis.Z ? -1 : 1); - return getSpeed() * -movementModifier / 512f; - } - - public Vec3d getConstructOffset(float partialTicks) { - float interpolatedOffset = - MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0, extensionLength); - return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(interpolatedOffset); - } - - @Override - public void attach(ContraptionEntity contraption) { - if (contraption.getContraption() instanceof PistonContraption) { - this.movedContraption = contraption; - if (!world.isRemote) - sendData(); - } - } - - @Override - public void onStall() { - if (!world.isRemote) - sendData(); - } - - @Override - public boolean isValid() { - return !isRemoved(); - } - } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index f4fdfd43f..15016f706 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -37,6 +37,16 @@ public class PistonContraption extends Contraption { protected int initialExtensionProgress; protected Direction orientation; + private static String type = "Piston"; + + static { + register(type, PistonContraption::new); + } + + @Override + protected String getType() { + return type; + } public static PistonContraption movePistonAt(World world, BlockPos pos, Direction direction, boolean retract) { if (isFrozen()) return null; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java new file mode 100644 index 000000000..5dc3d9bf4 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java @@ -0,0 +1,115 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.pulley; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.block.IHaveNoBlockItem; +import com.simibubi.create.foundation.utility.AllShapes; +import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.state.EnumProperty; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; + +public class PulleyBlock extends HorizontalAxisKineticBlock { + + public static EnumProperty HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS; + + public PulleyBlock() { + super(Properties.from(Blocks.ANDESITE)); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new PulleyTileEntity(); + } + + @Override + protected boolean hasStaticPart() { + return true; + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return AllShapes.PULLEY.get(state.get(HORIZONTAL_AXIS)); + } + + private static void onRopeBroken(World world, BlockPos pulleyPos) { + TileEntity te = world.getTileEntity(pulleyPos); + if (!(te instanceof PulleyTileEntity)) + return; + PulleyTileEntity pulley = (PulleyTileEntity) te; + pulley.offset = 0; + pulley.sendData(); + } + + private static class RopeBlockBase extends Block implements IHaveNoBlockItem { + + public RopeBlockBase(Properties properties) { + super(properties); + } + + @Override + public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, + boolean isMoving) { + if (isMoving) + return; + + if (fromPos.equals(pos.down()) && this != AllBlocks.PULLEY_MAGNET.get()) + if (!AllBlocks.ROPE.typeOf(worldIn.getBlockState(fromPos)) + && !AllBlocks.PULLEY_MAGNET.typeOf(worldIn.getBlockState(fromPos))) { + worldIn.destroyBlock(pos, true); + } + if (fromPos.equals(pos.up())) + if (!AllBlocks.ROPE.typeOf(worldIn.getBlockState(fromPos)) + && !AllBlocks.ROPE_PULLEY.typeOf(worldIn.getBlockState(fromPos))) { + worldIn.destroyBlock(pos, true); + } + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (!isMoving) + onRopeBroken(worldIn, pos.up()); + if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { + worldIn.removeTileEntity(pos); + } + } + + } + + public static class MagnetBlock extends RopeBlockBase { + + public MagnetBlock() { + super(Properties.from(Blocks.ANDESITE)); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return AllShapes.PULLEY_MAGNET; + } + + } + + public static class RopeBlock extends RopeBlockBase { + + public RopeBlock() { + super(Properties.from(Blocks.WHITE_WOOL)); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return AllShapes.FOUR_VOXEL_POLE.get(Direction.UP); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java new file mode 100644 index 000000000..c2972c8c4 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyContraption.java @@ -0,0 +1,49 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.pulley; + +import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class PulleyContraption extends Contraption { + + int initialOffset; + + private static String type = "Pulley"; + + static { + register(type, PulleyContraption::new); + } + + @Override + protected String getType() { + return type; + } + + public static PulleyContraption assemblePulleyAt(World world, BlockPos pos, int initialOffset) { + if (isFrozen()) + return null; + PulleyContraption construct = new PulleyContraption(); + construct.initialOffset = initialOffset; + if (!construct.searchMovedStructure(world, pos, Direction.DOWN)) + return null; + construct.initActors(world); + return construct; + } + + @Override + public CompoundNBT writeNBT() { + CompoundNBT writeNBT = super.writeNBT(); + writeNBT.putInt("InitialOffset", initialOffset); + return writeNBT; + } + + @Override + public void readNBT(World world, CompoundNBT nbt) { + initialOffset = nbt.getInt("InitialOffset"); + super.readNBT(world, nbt); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyRenderer.java new file mode 100644 index 000000000..7b8c22b04 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyRenderer.java @@ -0,0 +1,75 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.pulley; + +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.utility.SuperByteBuffer; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; + +import net.minecraft.block.BlockState; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; + +public class PulleyRenderer extends KineticTileEntityRenderer { + + @Override + public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, + BufferBuilder buffer) { + super.renderFast(te, x, y, z, partialTicks, destroyStage, buffer); + + PulleyTileEntity pulley = (PulleyTileEntity) te; + BlockState blockState = te.getBlockState(); + BlockPos pos = te.getPos(); + + SuperByteBuffer halfMagnet = AllBlockPartials.ROPE_HALF_MAGNET.renderOn(blockState); + SuperByteBuffer halfRope = AllBlockPartials.ROPE_HALF.renderOn(blockState); + SuperByteBuffer magnet = CreateClient.bufferCache.renderBlock(AllBlocks.PULLEY_MAGNET.getDefault()); + SuperByteBuffer rope = CreateClient.bufferCache.renderBlock(AllBlocks.ROPE.getDefault()); + + boolean moving = pulley.running && (pulley.movedContraption == null || !pulley.movedContraption.isStalled()); + float offset = pulley.getInterpolatedOffset(moving ? partialTicks : 0.5f); + + if (pulley.movedContraption != null) { + ContraptionEntity e = pulley.movedContraption; + PulleyContraption c = (PulleyContraption) pulley.movedContraption.getContraption(); + double entityPos = MathHelper.lerp(partialTicks, e.lastTickPosY, e.posY); + offset = (float) -(entityPos - c.getAnchor().getY() - c.initialOffset); + } + + if (pulley.running || pulley.offset == 0) + renderAt(offset > .25f ? magnet : halfMagnet, x, y, z, offset, pos, buffer); + + float f = offset % 1; + if (offset > .75f && (f < .25f || f > .75f)) + renderAt(halfRope, x, y, z, f > .75f ? f - 1 : f, pos, buffer); + + if (!pulley.running) + return; + + for (int i = 0; i < offset - 1.25f; i++) + renderAt(rope, x, y, z, offset - i - 1, pos, buffer); + } + + public void renderAt(SuperByteBuffer partial, double x, double y, double z, float offset, BlockPos pulleyPos, + BufferBuilder buffer) { + BlockPos actualPos = pulleyPos.down((int) offset); + int light = getWorld().getBlockState(actualPos).getPackedLightmapCoords(getWorld(), actualPos); + partial.translate(x, y - offset, z).light(light).renderInto(buffer); + } + + @Override + protected SuperByteBuffer getRotatedModel(KineticTileEntity te) { + BlockState blockState = te.getBlockState(); + return AllBlockPartials.ROPE_COIL.renderOnDirectional(blockState, horizontalFacing(blockState)); + } + + public Direction horizontalFacing(BlockState blockState) { + return Direction.getFacingFromAxis(AxisDirection.POSITIVE, blockState.get(PulleyBlock.HORIZONTAL_AXIS)); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java new file mode 100644 index 000000000..622fbe52f --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java @@ -0,0 +1,129 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.pulley; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.config.AllConfigs; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class PulleyTileEntity extends LinearActuatorTileEntity { + + public PulleyTileEntity() { + super(AllTileEntities.ROPE_PULLEY.type); + } + + @Override + public AxisAlignedBB getRenderBoundingBox() { + return super.getRenderBoundingBox().expand(0, -offset, 0); + } + + @Override + protected void assembleConstruct() { + if (speed == 0) + return; + if (offset >= getExtensionRange() && getSpeed() > 0) + return; + if (offset <= 0 && getSpeed() < 0) + return; + + if (!world.isRemote) { + for (int i = ((int) offset); i > 0; i--) { + BlockPos offset = pos.down(i); + world.setBlockState(offset, Blocks.AIR.getDefaultState(), 66); + } + + // Collect Construct + BlockPos anchor = pos.down((int) (offset + 1)); + PulleyContraption contraption = PulleyContraption.assemblePulleyAt(world, anchor, (int) offset); + if (contraption != null && !contraption.blocks.isEmpty()) { + contraption.removeBlocksFromWorld(world, BlockPos.ZERO); + movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this); + movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); + world.addEntity(movedContraption); + forceMove = true; + } + } + + running = true; + sendData(); + } + + @Override + protected void disassembleConstruct() { + if (!running) + return; + offset = getGridOffset(offset); + if (movedContraption != null) + applyContraptionPosition(); + + if (!world.isRemote) { + if (offset > 0) { + BlockPos magnetPos = pos.down((int) offset); + world.destroyBlock(magnetPos, + world.getBlockState(magnetPos).getCollisionShape(world, magnetPos).isEmpty()); + world.setBlockState(magnetPos, AllBlocks.PULLEY_MAGNET.getDefault(), 66); + } + + for (int i = 1; i <= ((int) offset) - 1; i++) { + BlockPos ropePos = pos.down(i); + world.destroyBlock(ropePos, world.getBlockState(ropePos).getCollisionShape(world, ropePos).isEmpty()); + } + for (int i = 1; i <= ((int) offset) - 1; i++) + world.setBlockState(pos.down(i), AllBlocks.ROPE.getDefault(), 66); + + if (movedContraption != null) + movedContraption.disassemble(); + } + + if (movedContraption != null) + movedContraption.remove(); + movedContraption = null; + running = false; + sendData(); + } + + @Override + protected Vec3d toPosition(float offset) { + if (movedContraption.getContraption() instanceof PulleyContraption) { + PulleyContraption contraption = (PulleyContraption) movedContraption.getContraption(); + return new Vec3d(contraption.getAnchor()).add(0, contraption.initialOffset - offset, 0); + + } + return Vec3d.ZERO; + } + + @Override + protected void visitNewPosition() { + if (world.isRemote) + return; + if (movedContraption != null) + return; + if (getSpeed() <= 0) + return; + + BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1); + BlockState stateBelow = world.getBlockState(posBelow); + if (stateBelow.getMaterial().isReplaceable() || stateBelow.getShape(world, posBelow).isEmpty()) + return; + + disassembleConstruct(); + assembleNextTick = true; + } + + @Override + protected int getExtensionRange() { + return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1); + } + + @Override + protected Vec3d toMotionVector(float speed) { + return new Vec3d(0, -speed, 0); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterBlock.java index 09950a856..9f13847b3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterBlock.java @@ -107,8 +107,11 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { MechanicalCrafterTileEntity crafter = CrafterHelper.getCrafter(worldIn, pos); - if (crafter != null) + if (crafter != null) { + if (crafter.covered) + Block.spawnAsEntity(worldIn, pos, AllItems.SLOT_COVER.asStack()); crafter.ejectWholeGrid(); + } for (Direction direction : Direction.values()) { if (direction.getAxis() == state.get(HORIZONTAL_FACING).getAxis()) @@ -166,31 +169,55 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock if (!(te instanceof MechanicalCrafterTileEntity)) return false; MechanicalCrafterTileEntity crafter = (MechanicalCrafterTileEntity) te; + boolean wrenched = AllItems.WRENCH.typeOf(heldItem); if (hit.getFace() == state.get(HORIZONTAL_FACING)) { - if (crafter.phase != Phase.IDLE && !AllItems.WRENCH.typeOf(heldItem)) { + if (crafter.phase != Phase.IDLE && !wrenched) { crafter.ejectWholeGrid(); return true; } - if (crafter.phase == Phase.IDLE && !isHand && !AllItems.WRENCH.typeOf(heldItem)) { + if (crafter.phase == Phase.IDLE && !isHand && !wrenched) { if (worldIn.isRemote) return true; - LazyOptional capability = crafter - .getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); + + if (AllItems.SLOT_COVER.typeOf(heldItem)) { + if (crafter.covered) + return false; + crafter.covered = true; + crafter.markDirty(); + crafter.sendData(); + if (!player.isCreative()) + heldItem.shrink(1); + return true; + } + + LazyOptional capability = + crafter.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); if (!capability.isPresent()) return false; - ItemStack remainder = ItemHandlerHelper.insertItem(capability.orElse(new ItemStackHandler()), - heldItem.copy(), false); + ItemStack remainder = + ItemHandlerHelper.insertItem(capability.orElse(new ItemStackHandler()), heldItem.copy(), false); if (remainder.getCount() != heldItem.getCount()) player.setHeldItem(handIn, remainder); return true; } ItemStack inSlot = crafter.inventory.getStackInSlot(0); - if (inSlot.isEmpty()) + if (inSlot.isEmpty()) { + if (crafter.covered && !wrenched) { + if (worldIn.isRemote) + return true; + crafter.covered = false; + crafter.markDirty(); + crafter.sendData(); + if (!player.isCreative()) + player.inventory.placeItemBackInInventory(worldIn, AllItems.SLOT_COVER.asStack()); + return true; + } return false; + } if (!isHand && !ItemHandlerHelper.canItemStacksStack(heldItem, inSlot)) return false; if (worldIn.isRemote) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java index 809a74bc8..7c84d666f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java @@ -55,6 +55,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (phase != Phase.IDLE) return stack; + if (covered) + return stack; return super.insertItem(slot, stack, simulate); }; @@ -73,6 +75,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { protected boolean reRender; protected Phase phase; protected int countDown; + protected boolean covered; protected GroupedItems groupedItemsBeforeCraft; // for rendering on client private InsertingBehaviour inserting; @@ -120,6 +123,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { compound.putString("Phase", phase.name()); compound.putInt("CountDown", countDown); + compound.putBoolean("Cover", covered); return super.write(compound); } @@ -166,6 +170,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (phase.name().equals(name)) this.phase = phase; countDown = compound.getInt("CountDown"); + covered = compound.getBoolean("Cover"); super.read(compound); } @@ -368,7 +373,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { } public boolean craftingItemPresent() { - return !inventory.getStackInSlot(0).isEmpty(); + return !inventory.getStackInSlot(0).isEmpty() || covered; } protected void checkCompletedRecipe() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java index 605c1c2bc..9ee6e450d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java @@ -146,7 +146,7 @@ public class MechanicalCrafterTileEntityRenderer extends SafeTileEntityRenderer< Direction targetDirection = MechanicalCrafterBlock.getTargetDirection(blockState); BlockPos pos = te.getPos(); - if (te.phase != Phase.IDLE && te.phase != Phase.CRAFTING && te.phase != Phase.INSERTING) { + if ((te.covered || te.phase != Phase.IDLE) && te.phase != Phase.CRAFTING && te.phase != Phase.INSERTING) { SuperByteBuffer lidBuffer = renderAndTransform(AllBlockPartials.MECHANICAL_CRAFTER_LID, blockState, pos); lidBuffer.translate(x, y, z).renderInto(buffer); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java index b5747388e..727d5c61a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/EncasedBeltBlock.java @@ -1,5 +1,6 @@ package com.simibubi.create.modules.contraptions.relays.encased; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; @@ -185,7 +186,7 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock { @Override public String getName() { - return name().toLowerCase(); + return Lang.asId(name()); } } diff --git a/src/main/resources/assets/create/blockstates/clockwork_bearing.json b/src/main/resources/assets/create/blockstates/clockwork_bearing.json new file mode 100644 index 000000000..3eca6ae5e --- /dev/null +++ b/src/main/resources/assets/create/blockstates/clockwork_bearing.json @@ -0,0 +1,16 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "create:block/bearing/clockwork" + }, + "variants": { + "facing" : { + "up" : { }, + "down" : { "x": 180 }, + "north" : { "x": 90 }, + "east" : { "x": 90, "y": 90 }, + "south" : { "x": 90, "y": 180 }, + "west" : { "x": 90, "y": 270 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/mechanical_bearing.json b/src/main/resources/assets/create/blockstates/mechanical_bearing.json index 75d3f3ace..54f9c1964 100644 --- a/src/main/resources/assets/create/blockstates/mechanical_bearing.json +++ b/src/main/resources/assets/create/blockstates/mechanical_bearing.json @@ -1,7 +1,7 @@ { "forge_marker": 1, "defaults": { - "model": "create:block/mechanical_bearing_base" + "model": "create:block/bearing/regular" }, "variants": { "facing" : { diff --git a/src/main/resources/assets/create/blockstates/pulley_magnet.json b/src/main/resources/assets/create/blockstates/pulley_magnet.json new file mode 100644 index 000000000..eff11d04e --- /dev/null +++ b/src/main/resources/assets/create/blockstates/pulley_magnet.json @@ -0,0 +1,5 @@ +{ + "variants": { + "" : { "model": "create:block/pulley/magnet" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/rope.json b/src/main/resources/assets/create/blockstates/rope.json new file mode 100644 index 000000000..9890e2ac6 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/rope.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "create:block/pulley/rope" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/rope_pulley.json b/src/main/resources/assets/create/blockstates/rope_pulley.json new file mode 100644 index 000000000..8739b33a1 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/rope_pulley.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "create:block/pulley/casing" + }, + "variants": { + "axis": { + "z": { }, + "x": { "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 746143f91..d8487255c 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -26,6 +26,7 @@ "item.create.propeller": "Propeller", "item.create.whisk": "Whisk", "item.create.brass_hand": "Hand", + "item.create.slot_cover": "Crafter Slot Cover", "item.create.flour": "Wheat Flour", "item.create.dough": "Dough", "item.create.wrench": "Wrench", @@ -117,6 +118,10 @@ "block.create.mechanical_piston_head": "Mechanical Piston Head", "block.create.piston_pole": "Piston Extension Pole", "block.create.mechanical_bearing": "Mechanical Bearing", + "block.create.clockwork_bearing": "Clockwork Bearing", + "block.create.rope_pulley": "Rope Pulley", + "block.create.rope": "Rope", + "block.create.pulley_magnet": "Pulley Magnet", "block.create.translation_chassis": "Linear Chassis", "block.create.rotation_chassis": "Radial Chassis", @@ -991,6 +996,9 @@ "item.create.shadow_steel.tooltip": "SHADOW STEEL", "item.create.shadow_steel.tooltip.summary": "A Chromatic material forged _in_ _the_ _void._", + "item.create.slot_cover.tooltip": "SLOT COVER", + "item.create.slot_cover.tooltip.summary": "Used to mark a _Mechanical_ _Crafter_ as an empty slot in a recipe. Crafters do not necessarily have to form a full square grid, this cover find its use when there are recipes where _ingredients_ _are_ _diagonal_ to each other.", + "item.create.logistical_controller_calculation.tooltip": "WIP", "item.create.logistical_controller_request.tooltip": "WIP", "item.create.logistical_controller_storage.tooltip": "WIP", diff --git a/src/main/resources/assets/create/models/block/bearing/clockwork.json b/src/main/resources/assets/create/models/block/bearing/clockwork.json new file mode 100644 index 000000000..a41847e0c --- /dev/null +++ b/src/main/resources/assets/create/models/block/bearing/clockwork.json @@ -0,0 +1,9 @@ +{ + "parent": "create:block/bearing/regular", + "textures": { + "particle": "create:block/clockwork_bearing_side", + "gearbox": "create:block/brass_gearbox", + "bearing_side": "create:block/clockwork_bearing_side", + "brass_casing": "create:block/brass_casing" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_bearing_base.json b/src/main/resources/assets/create/models/block/bearing/regular.json similarity index 100% rename from src/main/resources/assets/create/models/block/mechanical_bearing_base.json rename to src/main/resources/assets/create/models/block/bearing/regular.json diff --git a/src/main/resources/assets/create/models/block/mechanical_bearing_top.json b/src/main/resources/assets/create/models/block/bearing/top.json similarity index 100% rename from src/main/resources/assets/create/models/block/mechanical_bearing_top.json rename to src/main/resources/assets/create/models/block/bearing/top.json diff --git a/src/main/resources/assets/create/models/block/pulley/casing.json b/src/main/resources/assets/create/models/block/pulley/casing.json new file mode 100644 index 000000000..54755b9b7 --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/casing.json @@ -0,0 +1,195 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "3": "create:block/gearbox_top", + "4": "create:block/gearbox", + "particle": "create:block/pulley_rope" + }, + "elements": [ + { + "name": "side", + "from": [2, 2, 14], + "to": [14, 14, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "north": {"uv": [2, 2, 14, 14], "texture": "#4"}, + "south": {"uv": [2, 2, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 0, 1, 12], "rotation": 270, "texture": "#3"}, + "down": {"uv": [2, 11, 14, 12], "texture": "#4"} + } + }, + { + "name": "side", + "from": [2, 2, 1], + "to": [14, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "north": {"uv": [14, 2, 2, 14], "texture": "#4"}, + "south": {"uv": [14, 2, 2, 14], "texture": "#4"}, + "up": {"uv": [1, 0, 0, 12], "rotation": 270, "texture": "#3"}, + "down": {"uv": [2, 12, 14, 11], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 2, 14], + "to": [2, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#4"}, + "east": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "west": {"uv": [14, 2, 16, 14], "texture": "#4"}, + "up": {"uv": [0, 14, 2, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 2, 0], + "to": [2, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "east": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "south": {"uv": [16, 2, 14, 14], "texture": "#4"}, + "west": {"uv": [16, 2, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 16, 2, 14], "texture": "#4"}, + "down": {"uv": [0, 2, 2, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [14, 2, 14], + "to": [16, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [2, 2, 0, 14], "rotation": 180, "texture": "#4"}, + "east": {"uv": [2, 2, 0, 14], "rotation": 180, "texture": "#3"}, + "south": {"uv": [16, 2, 14, 14], "rotation": 180, "texture": "#4"}, + "west": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "up": {"uv": [2, 14, 0, 16], "texture": "#4"}, + "down": {"uv": [2, 0, 0, 2], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [14, 2, 0], + "to": [16, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [14, 2, 16, 14], "rotation": 180, "texture": "#4"}, + "east": {"uv": [0, 2, 2, 14], "rotation": 180, "texture": "#3"}, + "south": {"uv": [0, 2, 2, 14], "rotation": 180, "texture": "#4"}, + "west": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "up": {"uv": [2, 16, 0, 14], "texture": "#4"}, + "down": {"uv": [2, 2, 0, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 0, 14], + "to": [16, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#4"}, + "east": {"uv": [0, 14, 2, 16], "texture": "#4"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#4"}, + "west": {"uv": [14, 14, 16, 16], "texture": "#4"}, + "up": {"uv": [0, 0, 12, 2], "texture": "#4"}, + "down": {"uv": [0, 14, 16, 16], "rotation": 180, "texture": "#3"} + } + }, + { + "name": "side_frame", + "from": [0, 14, 14], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 15, 8]}, + "faces": { + "north": {"uv": [0, 16, 16, 14], "texture": "#4"}, + "east": {"uv": [0, 16, 2, 14], "texture": "#4"}, + "south": {"uv": [0, 16, 16, 14], "texture": "#4"}, + "west": {"uv": [14, 16, 16, 14], "texture": "#4"}, + "up": {"uv": [0, 16, 16, 14], "rotation": 180, "texture": "#3"}, + "down": {"uv": [0, 2, 12, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 0, 0], + "to": [16, 2, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [16, 14, 0, 16], "texture": "#4"}, + "east": {"uv": [2, 14, 0, 16], "texture": "#4"}, + "south": {"uv": [16, 14, 0, 16], "texture": "#4"}, + "west": {"uv": [16, 14, 14, 16], "texture": "#4"}, + "up": {"uv": [0, 2, 12, 0], "texture": "#4"}, + "down": {"uv": [0, 14, 16, 16], "texture": "#3"} + } + }, + { + "name": "side_frame", + "from": [0, 14, 0], + "to": [16, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 15, 8]}, + "faces": { + "north": {"uv": [16, 16, 0, 14], "texture": "#4"}, + "east": {"uv": [2, 16, 0, 14], "texture": "#4"}, + "south": {"uv": [16, 16, 0, 14], "texture": "#4"}, + "west": {"uv": [16, 16, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 2, 16, 0], "rotation": 180, "texture": "#3"}, + "down": {"uv": [0, 0, 12, 2], "texture": "#4"} + } + }, + { + "name": "front", + "from": [1, 1, 2], + "to": [3, 3, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "east": {"uv": [2, 0, 14, 2], "texture": "#3"}, + "west": {"uv": [2, 14, 14, 16], "texture": "#3"}, + "up": {"uv": [2, 0, 14, 2], "rotation": 90, "texture": "#3"}, + "down": {"uv": [2, 14, 14, 16], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [13, 1, 2], + "to": [15, 3, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "east": {"uv": [14, 14, 2, 16], "texture": "#3"}, + "west": {"uv": [14, 0, 2, 2], "texture": "#3"}, + "up": {"uv": [2, 2, 14, 0], "rotation": 90, "texture": "#3"}, + "down": {"uv": [2, 16, 14, 14], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [13, 13, 2], + "to": [15, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]}, + "faces": { + "east": {"uv": [14, 16, 2, 14], "texture": "#3"}, + "west": {"uv": [14, 2, 2, 0], "texture": "#3"}, + "up": {"uv": [14, 16, 2, 14], "rotation": 90, "texture": "#3"}, + "down": {"uv": [14, 2, 2, 0], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [1, 13, 2], + "to": [3, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]}, + "faces": { + "east": {"uv": [2, 2, 14, 0], "texture": "#3"}, + "west": {"uv": [2, 16, 14, 14], "texture": "#3"}, + "up": {"uv": [14, 14, 2, 16], "rotation": 90, "texture": "#3"}, + "down": {"uv": [14, 0, 2, 2], "rotation": 90, "texture": "#3"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/item.json b/src/main/resources/assets/create/models/block/pulley/item.json new file mode 100644 index 000000000..3f09109d3 --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/item.json @@ -0,0 +1,323 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/axis", + "1": "create:block/axis_top", + "3": "create:block/gearbox_top", + "4": "create:block/gearbox", + "5": "create:block/pulley_rope", + "6": "create:block/pulley_magnet", + "particle": "create:block/pulley_magnet" + }, + "elements": [ + { + "name": "coil", + "from": [4, 4, 2], + "to": [12, 12, 14], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "east": {"uv": [0, 0, 12, 8], "texture": "#5"}, + "west": {"uv": [0, 0, 12, 8], "texture": "#5"}, + "up": {"uv": [0, 0, 12, 8], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 12, 8], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "coil", + "from": [3.5, 3.5, 9], + "to": [12.5, 12.5, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "north": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "east": {"uv": [0, 0, 4, 9], "texture": "#5"}, + "south": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "west": {"uv": [0, 0, 4, 9], "rotation": 180, "texture": "#5"}, + "up": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "coil", + "from": [3.5, 3.5, 3], + "to": [12.5, 12.5, 7], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "north": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "east": {"uv": [0, 0, 4, 9], "texture": "#5"}, + "south": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "west": {"uv": [0, 0, 4, 9], "rotation": 180, "texture": "#5"}, + "up": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "side", + "from": [2, 2, 14], + "to": [14, 14, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "north": {"uv": [2, 2, 14, 14], "texture": "#4"}, + "south": {"uv": [2, 2, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 0, 1, 12], "rotation": 270, "texture": "#3"}, + "down": {"uv": [2, 11, 14, 12], "texture": "#4"} + } + }, + { + "name": "side", + "from": [2, 2, 1], + "to": [14, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "north": {"uv": [14, 2, 2, 14], "texture": "#4"}, + "south": {"uv": [14, 2, 2, 14], "texture": "#4"}, + "up": {"uv": [1, 0, 0, 12], "rotation": 270, "texture": "#3"}, + "down": {"uv": [2, 12, 14, 11], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 2, 14], + "to": [2, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#4"}, + "east": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "west": {"uv": [14, 2, 16, 14], "texture": "#4"}, + "up": {"uv": [0, 14, 2, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 2, 0], + "to": [2, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "east": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "south": {"uv": [16, 2, 14, 14], "texture": "#4"}, + "west": {"uv": [16, 2, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 16, 2, 14], "texture": "#4"}, + "down": {"uv": [0, 2, 2, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [14, 2, 14], + "to": [16, 14, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [2, 2, 0, 14], "rotation": 180, "texture": "#4"}, + "east": {"uv": [2, 2, 0, 14], "rotation": 180, "texture": "#3"}, + "south": {"uv": [16, 2, 14, 14], "rotation": 180, "texture": "#4"}, + "west": {"uv": [2, 2, 0, 14], "texture": "#4"}, + "up": {"uv": [2, 14, 0, 16], "texture": "#4"}, + "down": {"uv": [2, 0, 0, 2], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [14, 2, 0], + "to": [16, 14, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [14, 2, 16, 14], "rotation": 180, "texture": "#4"}, + "east": {"uv": [0, 2, 2, 14], "rotation": 180, "texture": "#3"}, + "south": {"uv": [0, 2, 2, 14], "rotation": 180, "texture": "#4"}, + "west": {"uv": [0, 2, 2, 14], "texture": "#4"}, + "up": {"uv": [2, 16, 0, 14], "texture": "#4"}, + "down": {"uv": [2, 2, 0, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 0, 14], + "to": [16, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#4"}, + "east": {"uv": [0, 14, 2, 16], "texture": "#4"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#4"}, + "west": {"uv": [14, 14, 16, 16], "texture": "#4"}, + "up": {"uv": [0, 0, 12, 2], "texture": "#4"}, + "down": {"uv": [0, 14, 16, 16], "rotation": 180, "texture": "#3"} + } + }, + { + "name": "side_frame", + "from": [0, 14, 14], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 15, 8]}, + "faces": { + "north": {"uv": [0, 16, 16, 14], "texture": "#4"}, + "east": {"uv": [0, 16, 2, 14], "texture": "#4"}, + "south": {"uv": [0, 16, 16, 14], "texture": "#4"}, + "west": {"uv": [14, 16, 16, 14], "texture": "#4"}, + "up": {"uv": [0, 16, 16, 14], "rotation": 180, "texture": "#3"}, + "down": {"uv": [0, 2, 12, 0], "texture": "#4"} + } + }, + { + "name": "side_frame", + "from": [0, 0, 0], + "to": [16, 2, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [16, 14, 0, 16], "texture": "#4"}, + "east": {"uv": [2, 14, 0, 16], "texture": "#4"}, + "south": {"uv": [16, 14, 0, 16], "texture": "#4"}, + "west": {"uv": [16, 14, 14, 16], "texture": "#4"}, + "up": {"uv": [0, 2, 12, 0], "texture": "#4"}, + "down": {"uv": [0, 14, 16, 16], "texture": "#3"} + } + }, + { + "name": "side_frame", + "from": [0, 14, 0], + "to": [16, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 15, 8]}, + "faces": { + "north": {"uv": [16, 16, 0, 14], "texture": "#4"}, + "east": {"uv": [2, 16, 0, 14], "texture": "#4"}, + "south": {"uv": [16, 16, 0, 14], "texture": "#4"}, + "west": {"uv": [16, 16, 14, 14], "texture": "#4"}, + "up": {"uv": [0, 2, 16, 0], "rotation": 180, "texture": "#3"}, + "down": {"uv": [0, 0, 12, 2], "texture": "#4"} + } + }, + { + "name": "front", + "from": [1, 1, 2], + "to": [3, 3, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "east": {"uv": [2, 0, 14, 2], "texture": "#3"}, + "west": {"uv": [2, 14, 14, 16], "texture": "#3"}, + "up": {"uv": [2, 0, 14, 2], "rotation": 90, "texture": "#3"}, + "down": {"uv": [2, 14, 14, 16], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [13, 1, 2], + "to": [15, 3, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, + "faces": { + "east": {"uv": [14, 14, 2, 16], "texture": "#3"}, + "west": {"uv": [14, 0, 2, 2], "texture": "#3"}, + "up": {"uv": [2, 2, 14, 0], "rotation": 90, "texture": "#3"}, + "down": {"uv": [2, 16, 14, 14], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [13, 13, 2], + "to": [15, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]}, + "faces": { + "east": {"uv": [14, 16, 2, 14], "texture": "#3"}, + "west": {"uv": [14, 2, 2, 0], "texture": "#3"}, + "up": {"uv": [14, 16, 2, 14], "rotation": 90, "texture": "#3"}, + "down": {"uv": [14, 2, 2, 0], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "front", + "from": [1, 13, 2], + "to": [3, 15, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]}, + "faces": { + "east": {"uv": [2, 2, 14, 0], "texture": "#3"}, + "west": {"uv": [2, 16, 14, 14], "texture": "#3"}, + "up": {"uv": [14, 14, 2, 16], "rotation": 90, "texture": "#3"}, + "down": {"uv": [14, 0, 2, 2], "rotation": 90, "texture": "#3"} + } + }, + { + "name": "Axis", + "from": [6, 6, 0], + "to": [10, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#1"}, + "east": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#0"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#1"}, + "west": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#0"}, + "up": {"uv": [6, 0, 10, 16], "texture": "#0"}, + "down": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#0"} + } + }, + { + "name": "rope", + "from": [6, 2, 6], + "to": [10, 8, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [7.75, 0, 8]}, + "faces": { + "north": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "east": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "south": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "west": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "up": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#6"} + } + }, + { + "name": "magnet", + "from": [3, 0, 3], + "to": [13, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 23, 8]}, + "faces": { + "north": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "east": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "south": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "west": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "up": {"uv": [0, 0, 10, 10], "texture": "#6"}, + "down": {"uv": [0, 0, 10, 10], "texture": "#6"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0], + "scale": [0.625, 0.625, 0.625] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + { + "name": "shaft", + "origin": [8, 8, 8], + "children": [17] + }, + { + "name": "rope_half_magnet", + "origin": [8, 8, 8], + "children": [18, 19] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/magnet.json b/src/main/resources/assets/create/models/block/pulley/magnet.json new file mode 100644 index 000000000..1b44d7f3e --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/magnet.json @@ -0,0 +1,37 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "6": "create:block/pulley_magnet", + "particle": "create:block/pulley_magnet" + }, + "elements": [ + { + "name": "rope", + "from": [6, 2, 6], + "to": [10, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [7.75, 0, 8]}, + "faces": { + "north": {"uv": [12, 0, 16, 14], "texture": "#6"}, + "east": {"uv": [12, 0, 16, 14], "texture": "#6"}, + "south": {"uv": [12, 0, 16, 14], "texture": "#6"}, + "west": {"uv": [12, 0, 16, 14], "texture": "#6"}, + "up": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#6"} + } + }, + { + "name": "magnet", + "from": [3, 0, 3], + "to": [13, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 23, 8]}, + "faces": { + "north": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "east": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "south": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "west": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "up": {"uv": [0, 0, 10, 10], "texture": "#6"}, + "down": {"uv": [0, 0, 10, 10], "texture": "#6"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/rope.json b/src/main/resources/assets/create/models/block/pulley/rope.json new file mode 100644 index 000000000..832617702 --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/rope.json @@ -0,0 +1,24 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "5": "create:block/pulley_rope", + "particle": "create:block/pulley_rope" + }, + "elements": [ + { + "name": "rope", + "from": [6, 0, 6], + "to": [10, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [7.75, 0, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 16], "texture": "#5"}, + "east": {"uv": [0, 0, 4, 16], "texture": "#5"}, + "south": {"uv": [0, 0, 4, 16], "texture": "#5"}, + "west": {"uv": [0, 0, 4, 16], "texture": "#5"}, + "up": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 4], "texture": "#5"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/rope_coil.json b/src/main/resources/assets/create/models/block/pulley/rope_coil.json new file mode 100644 index 000000000..bbb85e18b --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/rope_coil.json @@ -0,0 +1,66 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/axis", + "1": "create:block/axis_top", + "5": "create:block/pulley_rope" + }, + "elements": [ + { + "name": "coil", + "from": [4, 4, 2], + "to": [12, 12, 14], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "east": {"uv": [0, 0, 12, 8], "texture": "#5"}, + "west": {"uv": [0, 0, 12, 8], "texture": "#5"}, + "up": {"uv": [0, 0, 12, 8], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 12, 8], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "coil", + "from": [3.5, 3.5, 9], + "to": [12.5, 12.5, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "north": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "east": {"uv": [0, 0, 4, 9], "texture": "#5"}, + "south": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "west": {"uv": [0, 0, 4, 9], "rotation": 180, "texture": "#5"}, + "up": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "coil", + "from": [3.5, 3.5, 3], + "to": [12.5, 12.5, 7], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, -10]}, + "faces": { + "north": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "east": {"uv": [0, 0, 4, 9], "texture": "#5"}, + "south": {"uv": [0, 0, 9, 9], "texture": "#5"}, + "west": {"uv": [0, 0, 4, 9], "rotation": 180, "texture": "#5"}, + "up": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 9], "rotation": 90, "texture": "#5"} + } + }, + { + "name": "Axis", + "from": [6, 6, 0], + "to": [10, 10, 16], + "shade": false, + "rotation": {"angle": 0, "axis": "x", "origin": [8, 1, 8]}, + "faces": { + "north": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#1"}, + "east": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#0"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#1"}, + "west": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#0"}, + "up": {"uv": [6, 0, 10, 16], "texture": "#0"}, + "down": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/rope_half.json b/src/main/resources/assets/create/models/block/pulley/rope_half.json new file mode 100644 index 000000000..522789073 --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/rope_half.json @@ -0,0 +1,24 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "5": "create:block/pulley_rope", + "particle": "create:block/pulley_rope" + }, + "elements": [ + { + "name": "rope", + "from": [6, 0, 6], + "to": [10, 8, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [7.75, 0, 8]}, + "faces": { + "north": {"uv": [0, 8, 4, 16], "texture": "#5"}, + "east": {"uv": [0, 8, 4, 16], "texture": "#5"}, + "south": {"uv": [0, 8, 4, 16], "texture": "#5"}, + "west": {"uv": [0, 8, 4, 16], "texture": "#5"}, + "up": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#5"}, + "down": {"uv": [0, 0, 4, 4], "texture": "#5"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/pulley/rope_half_magnet.json b/src/main/resources/assets/create/models/block/pulley/rope_half_magnet.json new file mode 100644 index 000000000..f3f8f43c2 --- /dev/null +++ b/src/main/resources/assets/create/models/block/pulley/rope_half_magnet.json @@ -0,0 +1,37 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "6": "create:block/pulley_magnet", + "particle": "create:block/pulley_magnet" + }, + "elements": [ + { + "name": "rope", + "from": [6, 2, 6], + "to": [10, 8, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [7.75, 0, 8]}, + "faces": { + "north": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "east": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "south": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "west": {"uv": [12, 8, 16, 14], "texture": "#6"}, + "up": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#6"} + } + }, + { + "name": "magnet", + "from": [3, 0, 3], + "to": [13, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 23, 8]}, + "faces": { + "north": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "east": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "south": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "west": {"uv": [0, 10, 10, 12], "texture": "#6"}, + "up": {"uv": [0, 0, 10, 10], "texture": "#6"}, + "down": {"uv": [0, 0, 10, 10], "texture": "#6"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/clockwork_bearing.json b/src/main/resources/assets/create/models/item/clockwork_bearing.json new file mode 100644 index 000000000..5dfaa81ab --- /dev/null +++ b/src/main/resources/assets/create/models/item/clockwork_bearing.json @@ -0,0 +1,9 @@ +{ + "parent": "create:item/mechanical_bearing", + "textures": { + "particle": "create:block/clockwork_bearing_side", + "bearing_top": "create:block/bearing_top", + "gearbox": "create:block/brass_gearbox", + "bearing_side": "create:block/clockwork_bearing_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/rope_pulley.json b/src/main/resources/assets/create/models/item/rope_pulley.json new file mode 100644 index 000000000..9842abe5f --- /dev/null +++ b/src/main/resources/assets/create/models/item/rope_pulley.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/pulley/item" +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/slot_cover.json b/src/main/resources/assets/create/models/item/slot_cover.json new file mode 100644 index 000000000..254fd6725 --- /dev/null +++ b/src/main/resources/assets/create/models/item/slot_cover.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "create:item/slot_cover" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png b/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png new file mode 100644 index 0000000000000000000000000000000000000000..2b245c55ac7db15060378323176dbbf7c86baa12 GIT binary patch literal 500 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0f|XOK~y+Tol-qd z!!QuFlg9aIX-d_qf*Da!@h9lo0g0&_8yg!V3u0&FH-cJ0Qy_L6JK?z(+6po8hNpMW zclMoaKAX)LW5$@euC29TpsFgELI}<|1c4IxbUN+#`;Es~7=|Q@q96eW8oXMqq?CLz znV^93ekGA02WSe$<8fpBU_S}i?n2 zz|cw?m&I7W*8#sSGk$jLRM_$ov8mCvFwJIU!hznJ{Ngm~c6!>@2$I;<7~QM^`@T{( z&oh2LV!bF>sq!!u?^3r#u(rFQ2SP8_de{}Rf63SKsHvFq7CV<JLf)0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGizW@LZzX3P}QzQTY0Tf9@K~y+Tl~O%V z!!Q)|i;YuEG2D~l(00tnv|(n zR_!qcTW|zhW_p@lhOrQv$_-K-%n!?;yX%SfV&z&hE)L#SUl6zyhkKxlvq7F8L#@~E z;9f0H$63?3EF0p1=+();&V!R*cAYx;<9kudlaj3cP)g&0=+$j-_^!|bvF^qPbPnnM z<{asCX2j6SySnWNBm4p2@NpG+F-PnU>G|~qBa|=fjz-{m6RHaE3I$~y>dj?Fd%@8H dJc(8a@eNm4!8@Pe=H37R002ovPDHLkV1jr>p`ZW& literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/pulley_magnet.png b/src/main/resources/assets/create/textures/block/pulley_magnet.png new file mode 100644 index 0000000000000000000000000000000000000000..745d3e704ef3141fa449ffade72375b1f4f885b8 GIT binary patch literal 542 zcmV+(0^$9MP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!Tc8q$xon+>8U5*v@l7>!1lPN!mIu~>*FDaXXyat+(E z5vE+2Jf`pa^0U=yq0wldTCJklY{GFIDNe6>Rmp_OfomO4K(^a0hQlESg8}CAIVO{d ztg-lCeH_b@YcP4aj*l9!3t^I`R4V;O=K`nwW9RwD7q)w)!SA{plS#Q;4wXs;<#Jip zS$wrxNld6gwERMnBvQ=Q$0Y4`TYSIY7q8(SO{6*->I+jIu6zfk7AT+3pR8Cco=g|l z@W`3qn9MmaYPFgS61(hnJBF}rTRhPXdcB?u((~hOqUXRe)hh%+AR-xtA)9H8X&fZ& zHUHz173q% gT;M7_xI;c&VvweD$_w-|vs+*4X zD%`fSX!lyWarg1}b8HSa`F(wRm4A-!lFbqCSF^2ubnk4y4e6?er*AH$DmN$0+qF*3 z-}NoWT!n*@b6Gsn+0u*sRan%RclJppx4Guk*vCuWGkpHv{?9-Djdje=*N9(eRCQ1W PdXT}>)z4*}Q$iB}=Ea4$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/slot_cover.png b/src/main/resources/assets/create/textures/item/slot_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3c701dc5d28e3d974e19ae00ba07710d842767 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!CRg#jv*HQ$$$R;w`W#u;Pjfzt6|1)nEU0$ zFpIw>FMk=gJ$^1{;IuQLA&J4GICP!)6m~}YegB&-*ejN}T`dxE-cXhJ^w;5pUj6xY z?Ad>Qywg2=?(g%3n^rJfZK$t5IAwpkWrVP`x&Gnv>*pWb(ma#v@Ll%pk`n*^Gp}xB zT%+f3oo7)YBM-BKpL&=vM?xv%##xRGmst-uSQotFyCWdM(3!}r!4|XYr;yKXYpJHp zfCaXdf0=qhMJgrY>RMQgj1G8sOlvEuFh2hAbAN%lN)f{~2Nl+U3^TacFh0) literal 0 HcmV?d00001 diff --git a/src/main/resources/data/create/loot_tables/blocks/clockwork_bearing.json b/src/main/resources/data/create/loot_tables/blocks/clockwork_bearing.json new file mode 100644 index 000000000..7903024cb --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/clockwork_bearing.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:clockwork_bearing" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/loot_tables/blocks/rope_pulley.json b/src/main/resources/data/create/loot_tables/blocks/rope_pulley.json new file mode 100644 index 000000000..fa0c48f95 --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/rope_pulley.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:rope_pulley" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/clockwork_bearing.json b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/clockwork_bearing.json new file mode 100644 index 000000000..fa7091d71 --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/clockwork_bearing.json @@ -0,0 +1,32 @@ +{ + "type": "crafting_shaped", + "pattern": [ + " B ", + "SCS", + " I " + ], + "key": { + "S": { + "item": "create:electron_tube" + }, + "B": { + "item": "create:turntable" + }, + "C": { + "item": "create:brass_casing" + }, + "I": { + "item": "create:shaft" + } + }, + "result": { + "item": "create:clockwork_bearing", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "contraptions" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/mechanical_crafter.json b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/mechanical_crafter.json index 8414d2989..fcf6efa70 100644 --- a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/mechanical_crafter.json +++ b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/mechanical_crafter.json @@ -25,7 +25,7 @@ }, "result": { "item": "create:mechanical_crafter", - "count": 1 + "count": 3 }, "conditions": [ { diff --git a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/rope_pulley.json b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/rope_pulley.json new file mode 100644 index 000000000..1b86ec51e --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/rope_pulley.json @@ -0,0 +1,32 @@ +{ + "type": "crafting_shaped", + "pattern": [ + " B ", + "SCS", + " I " + ], + "key": { + "S": { + "item": "create:shaft" + }, + "B": { + "item": "create:andesite_casing" + }, + "C": { + "tag": "minecraft:wool" + }, + "I": { + "tag": "forge:plates/iron" + } + }, + "result": { + "item": "create:rope_pulley", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "contraptions" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/slot_cover.json b/src/main/resources/data/create/recipes/crafting_shaped/slot_cover.json new file mode 100644 index 000000000..12c8045f1 --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/slot_cover.json @@ -0,0 +1,21 @@ +{ + "type": "crafting_shaped", + "pattern": [ + "AAA" + ], + "key": { + "A": { + "tag": "forge:nuggets/brass" + } + }, + "result": { + "item": "create:slot_cover", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "contraptions" + } + ] +} \ No newline at end of file