From 9f6022f0fe708f424c56363b10c579b7cc71656a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 5 Dec 2019 23:42:01 +0100 Subject: [PATCH] Colors and Sparkles - Linear Chassis (formerly translation chassis) now connect textures - Added Engineer's Goggles - Added Custom Particle for Speed level indications - Added Volcanic Rock and the ability to give blocks smooth colors based on their position --- .../java/com/simibubi/create/AllBlocks.java | 28 +-- .../com/simibubi/create/AllContainers.java | 8 +- .../java/com/simibubi/create/AllItems.java | 11 +- .../com/simibubi/create/AllParticles.java | 88 ++++++++++ .../com/simibubi/create/AllTileEntities.java | 14 +- src/main/java/com/simibubi/create/Create.java | 43 ++--- .../com/simibubi/create/CreateClient.java | 46 ++++- .../com/simibubi/create/CreateConfig.java | 6 +- .../create/ResourceReloadHandler.java | 2 +- .../create/foundation/block/CTModel.java | 19 +- .../foundation/block/ColoredVertexModel.java | 71 ++++++++ .../block/IBlockWithColoredVertices.java | 7 + .../block/IHaveConnectedTextures.java | 44 ++++- .../foundation/block/SpriteShifter.java | 9 +- .../modules/contraptions/GogglesItem.java | 49 ++++++ .../base/GeneratingKineticTileEntity.java | 10 ++ .../modules/contraptions/base/IRotate.java | 13 ++ .../contraptions/base/KineticBlock.java | 22 +++ .../contraptions/base/KineticTileEntity.java | 61 +++++++ .../generators/WaterWheelBlock.java | 10 ++ .../particle/RotationIndicatorParticle.java | 102 +++++++++++ .../RotationIndicatorParticleData.java | 82 +++++++++ .../receivers/CrushingWheelBlock.java | 10 ++ .../receivers/MechanicalMixerBlock.java | 10 ++ .../receivers/constructs/Contraption.java | 117 +++++++++++-- .../constructs/IHaveMovementBehavior.java | 1 + ...ssisBlock.java => LinearChassisBlock.java} | 32 +++- ...ssisBlock.java => RadialChassisBlock.java} | 16 +- .../{ => bearing}/MechanicalBearingBlock.java | 2 +- .../MechanicalBearingTileEntity.java | 3 +- .../MechanicalBearingTileEntityRenderer.java | 2 +- .../{ => bearing}/RotationConstruct.java | 6 +- .../RotationConstructVertexBuffer.java | 2 +- .../constructs/mounted/ContraptionEntity.java | 4 + .../{ => piston}/MechanicalPistonBlock.java | 2 +- .../MechanicalPistonHeadBlock.java | 4 +- .../MechanicalPistonTileEntity.java | 7 +- .../MechanicalPistonTileEntityRenderer.java | 3 +- .../{ => piston}/MovingConstructHandler.java | 3 +- .../{ => piston}/PistonContraption.java | 5 +- .../{ => piston}/PistonPoleBlock.java | 5 +- .../crafter/MechanicalCrafterBlock.java | 14 +- .../contraptions/relays/CogWheelBlock.java | 10 ++ .../contraptions/relays/ShaftBlock.java | 10 ++ .../relays/belt/BeltTunnelTileEntity.java | 15 +- .../block/belts/ExtractorTileEntity.java | 16 +- .../create/modules/palettes/CTGlassBlock.java | 14 -- .../modules/palettes/VolcanicRockBlock.java | 41 +++++ .../create/blockstates/volcanic_rock.json | 5 + .../resources/assets/create/lang/en_us.json | 22 ++- .../models/block/palettes/volcanic_rock.json | 6 + .../assets/create/models/item/goggles.json | 164 ++++++++++++++++++ .../create/models/item/volcanic_rock.json | 3 + .../create/particles/rotation_indicator.json | 12 ++ .../connected/translation_chassis_top.png | Bin 0 -> 4895 bytes .../translation_chassis_top_sticky.png | Bin 0 -> 5141 bytes .../create/textures/block/volcanic_rock.png | Bin 0 -> 682 bytes .../assets/create/textures/gui/filter.pdn | Bin 13643 -> 9152 bytes .../assets/create/textures/item/goggles.png | Bin 0 -> 361 bytes .../loot_tables/blocks/belt_support.json | 19 -- .../create/recipes/crafting/belt_support.json | 26 --- .../create/recipes/pressing/sugar_cane.json | 16 ++ 62 files changed, 1168 insertions(+), 204 deletions(-) create mode 100644 src/main/java/com/simibubi/create/AllParticles.java create mode 100644 src/main/java/com/simibubi/create/foundation/block/ColoredVertexModel.java create mode 100644 src/main/java/com/simibubi/create/foundation/block/IBlockWithColoredVertices.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/GogglesItem.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticleData.java rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{TranslationChassisBlock.java => LinearChassisBlock.java} (64%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{RotationChassisBlock.java => RadialChassisBlock.java} (95%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => bearing}/MechanicalBearingBlock.java (99%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => bearing}/MechanicalBearingTileEntity.java (98%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => bearing}/MechanicalBearingTileEntityRenderer.java (99%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => bearing}/RotationConstruct.java (95%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => bearing}/RotationConstructVertexBuffer.java (98%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/MechanicalPistonBlock.java (99%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/MechanicalPistonHeadBlock.java (98%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/MechanicalPistonTileEntity.java (98%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/MechanicalPistonTileEntityRenderer.java (93%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/MovingConstructHandler.java (98%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/PistonContraption.java (97%) rename src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/{ => piston}/PistonPoleBlock.java (98%) create mode 100644 src/main/java/com/simibubi/create/modules/palettes/VolcanicRockBlock.java create mode 100644 src/main/resources/assets/create/blockstates/volcanic_rock.json create mode 100644 src/main/resources/assets/create/models/block/palettes/volcanic_rock.json create mode 100644 src/main/resources/assets/create/models/item/goggles.json create mode 100644 src/main/resources/assets/create/models/item/volcanic_rock.json create mode 100644 src/main/resources/assets/create/particles/rotation_indicator.json create mode 100644 src/main/resources/assets/create/textures/block/connected/translation_chassis_top.png create mode 100644 src/main/resources/assets/create/textures/block/connected/translation_chassis_top_sticky.png create mode 100644 src/main/resources/assets/create/textures/block/volcanic_rock.png create mode 100644 src/main/resources/assets/create/textures/item/goggles.png delete mode 100644 src/main/resources/data/create/loot_tables/blocks/belt_support.json delete mode 100644 src/main/resources/data/create/recipes/crafting/belt_support.json create mode 100644 src/main/resources/data/create/recipes/pressing/sugar_cane.json diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 845ddd674..656dc417d 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -23,14 +23,14 @@ import com.simibubi.create.modules.contraptions.receivers.MechanicalMixerBlock.M import com.simibubi.create.modules.contraptions.receivers.MechanicalPressBlock; import com.simibubi.create.modules.contraptions.receivers.SawBlock; import com.simibubi.create.modules.contraptions.receivers.TurntableBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonHeadBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.PistonPoleBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.RotationChassisBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.TranslationChassisBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.LinearChassisBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.RadialChassisBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.mounted.CartAssemblerBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.mounted.CartAssemblerBlock.MinecartAnchorBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonHeadBlock; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.PistonPoleBlock; import com.simibubi.create.modules.contraptions.receivers.crafter.MechanicalCrafterBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.relays.ClutchBlock; @@ -65,6 +65,7 @@ import com.simibubi.create.modules.logistics.transport.villager.LogisticiansTabl import com.simibubi.create.modules.logistics.transport.villager.PackageFunnelBlock; import com.simibubi.create.modules.palettes.CTGlassBlock; import com.simibubi.create.modules.palettes.GlassPaneBlock; +import com.simibubi.create.modules.palettes.VolcanicRockBlock; import com.simibubi.create.modules.schematics.block.CreativeCrateBlock; import com.simibubi.create.modules.schematics.block.SchematicTableBlock; import com.simibubi.create.modules.schematics.block.SchematicannonBlock; @@ -86,6 +87,7 @@ import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.registries.IForgeRegistry; public enum AllBlocks { @@ -130,16 +132,16 @@ public enum AllBlocks { MECHANICAL_CRAFTER_ARROW(new RenderUtilityDirectionalBlock()), MECHANICAL_CRAFTER_BELT_FRAME(new RenderUtilityDirectionalBlock()), MECHANICAL_CRAFTER_BELT(new RenderUtilityDirectionalBlock()), - + MECHANICAL_PISTON(new MechanicalPistonBlock(false)), STICKY_MECHANICAL_PISTON(new MechanicalPistonBlock(true)), MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()), PISTON_POLE(new PistonPoleBlock()), MECHANICAL_BEARING(new MechanicalBearingBlock()), MECHANICAL_BEARING_TOP(new ShaftHalfBlock()), - TRANSLATION_CHASSIS(new TranslationChassisBlock()), - TRANSLATION_CHASSIS_SECONDARY(new TranslationChassisBlock()), - ROTATION_CHASSIS(new RotationChassisBlock()), + TRANSLATION_CHASSIS(new LinearChassisBlock()), + TRANSLATION_CHASSIS_SECONDARY(new LinearChassisBlock()), + ROTATION_CHASSIS(new RadialChassisBlock()), DRILL(new DrillBlock()), DRILL_HEAD(new DrillHeadBlock()), SAW(new SawBlock()), @@ -209,6 +211,8 @@ public enum AllBlocks { POLISHED_DOLOMITE(new Block(Properties.from(DOLOMITE.block))), DOLOMITE_PILLAR(new RotatedPillarBlock(Properties.from(DOLOMITE.block))), + VOLCANIC_ROCK(new VolcanicRockBlock()), + ; private enum ComesWith { @@ -242,7 +246,9 @@ public enum AllBlocks { alsoRegistered[i] = makeRelatedBlock(block, comesWith[i]); } - public static void registerBlocks(IForgeRegistry registry) { + public static void register(RegistryEvent.Register event) { + IForgeRegistry registry = event.getRegistry(); + for (AllBlocks block : values()) { if (block.get() == null) continue; diff --git a/src/main/java/com/simibubi/create/AllContainers.java b/src/main/java/com/simibubi/create/AllContainers.java index b947d6674..d14325d20 100644 --- a/src/main/java/com/simibubi/create/AllContainers.java +++ b/src/main/java/com/simibubi/create/AllContainers.java @@ -22,8 +22,8 @@ import net.minecraft.inventory.container.ContainerType.IFactory; import net.minecraft.util.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.network.IContainerFactory; -import net.minecraftforge.registries.IForgeRegistry; public enum AllContainers { @@ -32,7 +32,7 @@ public enum AllContainers { FLEXCRATE(FlexcrateContainer::new), LOGISTICAL_INDEX(LogisticalIndexContainer::new), LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new), - + ; public ContainerType type; @@ -42,11 +42,11 @@ public enum AllContainers { this.factory = factory; } - public static void registerContainers(IForgeRegistry> iForgeRegistry) { + public static void register(RegistryEvent.Register> event) { for (AllContainers container : values()) { container.type = new ContainerType<>(container.factory) .setRegistryName(new ResourceLocation(Create.ID, Lang.asId(container.name()))); - iForgeRegistry.register(container.type); + event.getRegistry().register(container.type); } } diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index b5069679b..54a11fb56 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -3,6 +3,7 @@ package com.simibubi.create; import com.simibubi.create.foundation.item.IItemWithColorHandler; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.IModule; +import com.simibubi.create.modules.contraptions.GogglesItem; import com.simibubi.create.modules.contraptions.WrenchItem; import com.simibubi.create.modules.contraptions.WrenchItemRenderer; import com.simibubi.create.modules.contraptions.relays.VerticalGearboxItem; @@ -32,6 +33,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Rarity; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.registries.IForgeRegistry; @@ -88,6 +90,7 @@ public enum AllItems { DOUGH(ingredient()), PROPELLER(ingredient()), WRENCH(new WrenchItem(standardItemProperties().setTEISR(() -> () -> renderUsing(AllItemRenderers.WRENCH)))), + GOGGLES(new GogglesItem(standardItemProperties())), CRUSHED_IRON(ingredient()), CRUSHED_GOLD(ingredient()), @@ -146,12 +149,16 @@ public enum AllItems { return new Item(standardItemProperties().rarity(rarity)); } - public static void registerItems(IForgeRegistry iForgeRegistry) { + public static void register(RegistryEvent.Register event) { + IForgeRegistry registry = event.getRegistry(); + for (AllItems item : values()) { if (item.get() == null) continue; - iForgeRegistry.register(item.get()); + registry.register(item.get()); } + + AllBlocks.registerItemBlocks(registry); } public Item get() { diff --git a/src/main/java/com/simibubi/create/AllParticles.java b/src/main/java/com/simibubi/create/AllParticles.java new file mode 100644 index 000000000..37c95fbf2 --- /dev/null +++ b/src/main/java/com/simibubi/create/AllParticles.java @@ -0,0 +1,88 @@ +package com.simibubi.create; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.client.particle.ParticleManager.IParticleMetaFactory; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.ParticleFactoryRegisterEvent; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.registries.IForgeRegistry; + +public enum AllParticles { + + ROTATION_INDICATOR(RotationIndicatorParticle.Type::new, RotationIndicatorParticle.Factory::new), + + ; + + private ParticleEntry entry; + + private AllParticles(Supplier> typeFactory, + IParticleMetaFactory particleFactory) { + String asId = Lang.asId(this.name().toLowerCase()); + entry = new ParticleEntry(new ResourceLocation(Create.ID, asId), typeFactory, particleFactory); + } + + public static void register(RegistryEvent.Register> event) { + for (AllParticles particle : values()) + particle.entry.register(event.getRegistry()); + } + + public static void registerFactories(ParticleFactoryRegisterEvent event) { + ParticleManager particles = Minecraft.getInstance().particles; + for (AllParticles particle : values()) + particle.entry.registerFactory(particles); + } + + public ParticleType get() { + return entry.getType(); + } + + public String parameter() { + return Lang.asId(name()); + } + + private class ParticleEntry { + Supplier> typeFactory; + IParticleMetaFactory particleFactory; + ParticleType type; + ResourceLocation id; + + public ParticleEntry(ResourceLocation id, Supplier> typeFactory, + IParticleMetaFactory particleFactory) { + this.id = id; + this.typeFactory = typeFactory; + this.particleFactory = particleFactory; + } + + ParticleType getType() { + makeType(); + return type; + } + + void register(IForgeRegistry> registry) { + makeType(); + registry.register(type); + } + + void makeType() { + if (type == null) { + type = typeFactory.get(); + type.setRegistryName(id); + } + } + + void registerFactory(ParticleManager particles) { + makeType(); + particles.registerFactory(type, particleFactory); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index f245059f2..00651bd74 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -25,10 +25,10 @@ import com.simibubi.create.modules.contraptions.receivers.SawTileEntity; import com.simibubi.create.modules.contraptions.receivers.SawTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.TurntableTileEntity; import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisTileEntity; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntity; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer; +import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntity; +import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntityRenderer; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonTileEntity; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.modules.contraptions.receivers.crafter.MechanicalCrafterTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.ClutchTileEntity; @@ -81,8 +81,8 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.registries.IForgeRegistry; public enum AllTileEntities { @@ -153,7 +153,7 @@ public enum AllTileEntities { return te.getType().equals(type); } - public static void registerTileEntities(IForgeRegistry> registry) { + public static void register(RegistryEvent.Register> event) { for (AllTileEntities tileEntity : values()) { Block[] blocks = new Block[tileEntity.blocks.length]; for (int i = 0; i < blocks.length; i++) @@ -162,7 +162,7 @@ public enum AllTileEntities { ResourceLocation resourceLocation = new ResourceLocation(Create.ID, Lang.asId(tileEntity.name())); tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null) .setRegistryName(resourceLocation); - registry.register(tileEntity.type); + event.getRegistry().register(tileEntity.type); } } diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 8e571000c..0810a3bf6 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -5,7 +5,7 @@ import org.apache.logging.log4j.Logger; import com.simibubi.create.modules.ModuleLoadedCondition; import com.simibubi.create.modules.contraptions.TorquePropagator; -import com.simibubi.create.modules.contraptions.receivers.constructs.MovingConstructHandler; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MovingConstructHandler; import com.simibubi.create.modules.logistics.FrequencyHandler; import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler; import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler; @@ -18,6 +18,7 @@ import net.minecraft.inventory.container.ContainerType; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.particles.ParticleType; import net.minecraft.tileentity.TileEntityType; import net.minecraft.village.PointOfInterestType; import net.minecraftforge.common.crafting.CraftingHelper; @@ -51,14 +52,17 @@ public class Create { public Create() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); modEventBus.addListener(Create::init); - modEventBus.addGenericListener(Block.class, Create::registerBlocks); - modEventBus.addGenericListener(Item.class, Create::registerItems); - modEventBus.addGenericListener(IRecipeSerializer.class, Create::registerRecipes); - modEventBus.addGenericListener(TileEntityType.class, Create::registerTileEntities); - modEventBus.addGenericListener(ContainerType.class, Create::registerContainers); + + modEventBus.addGenericListener(Block.class, AllBlocks::register); + modEventBus.addGenericListener(Item.class, AllItems::register); + modEventBus.addGenericListener(IRecipeSerializer.class, AllRecipes::register); + modEventBus.addGenericListener(TileEntityType.class, AllTileEntities::register); + modEventBus.addGenericListener(ContainerType.class, AllContainers::register); modEventBus.addGenericListener(VillagerProfession.class, Create::registerVillagerProfessions); modEventBus.addGenericListener(PointOfInterestType.class, Create::registerPointsOfInterest); - modEventBus.addGenericListener(EntityType.class, Create::registerEntities); + modEventBus.addGenericListener(EntityType.class, AllEntities::register); + modEventBus.addGenericListener(ParticleType.class, AllParticles::register); + modEventBus.addListener(Create::createConfigs); CreateClient.addListeners(modEventBus); @@ -77,31 +81,6 @@ public class Create { AllPackets.registerPackets(); } - public static void registerItems(RegistryEvent.Register event) { - AllItems.registerItems(event.getRegistry()); - AllBlocks.registerItemBlocks(event.getRegistry()); - } - - public static void registerBlocks(RegistryEvent.Register event) { - AllBlocks.registerBlocks(event.getRegistry()); - } - - public static void registerTileEntities(RegistryEvent.Register> event) { - AllTileEntities.registerTileEntities(event.getRegistry()); - } - - public static void registerContainers(RegistryEvent.Register> event) { - AllContainers.registerContainers(event.getRegistry()); - } - - public static void registerRecipes(RegistryEvent.Register> event) { - AllRecipes.register(event); - } - - public static void registerEntities(final RegistryEvent.Register> event) { - AllEntities.register(event); - } - public static void registerVillagerProfessions(RegistryEvent.Register event) { LogisticianHandler.registerVillagerProfessions(event); } diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index f14f31087..4ab00aca4 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -1,11 +1,15 @@ package com.simibubi.create; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.function.Function; import com.simibubi.create.foundation.block.CTModel; +import com.simibubi.create.foundation.block.ColoredVertexModel; +import com.simibubi.create.foundation.block.IBlockWithColoredVertices; import com.simibubi.create.foundation.block.IHaveConnectedTextures; -import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry; import com.simibubi.create.foundation.utility.SuperByteBufferCache; import com.simibubi.create.modules.contraptions.WrenchModel; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; @@ -20,6 +24,7 @@ import com.simibubi.create.modules.schematics.client.SchematicAndQuillHandler; import com.simibubi.create.modules.schematics.client.SchematicHandler; import com.simibubi.create.modules.schematics.client.SchematicHologram; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockModelShapes; import net.minecraft.client.renderer.model.IBakedModel; @@ -58,6 +63,7 @@ public class CreateClient { modEventBus.addListener(CreateClient::onModelBake); modEventBus.addListener(CreateClient::onModelRegistry); modEventBus.addListener(CreateClient::onTextureStitch); + modEventBus.addListener(AllParticles::registerFactories); }); } @@ -103,9 +109,11 @@ public class CreateClient { if (!event.getMap().getBasePath().equals("textures")) return; for (AllBlocks allBlocks : AllBlocks.values()) { - if (!(allBlocks.get() instanceof IHaveConnectedTextures)) + Block block = allBlocks.get(); + if (!(block instanceof IHaveConnectedTextures)) continue; - event.addSprite(new ResourceLocation(Create.ID, "block/connected/" + Lang.asId(allBlocks.name()))); + for (SpriteShiftEntry spriteShiftEntry : ((IHaveConnectedTextures) block).getSpriteShifts()) + event.addSprite(spriteShiftEntry.getTargetResourceLocation()); } } @@ -114,10 +122,17 @@ public class CreateClient { Map modelRegistry = event.getModelRegistry(); for (AllBlocks allBlocks : AllBlocks.values()) { - if (!(allBlocks.get() instanceof IHaveConnectedTextures)) + Block block = allBlocks.get(); + if (block == null) continue; - swapModels(modelRegistry, getBlockModelLocation(allBlocks, ""), - t -> new CTModel(t, Lang.asId(allBlocks.name()))); + + List blockModelLocations = getAllBlockStateModelLocations(allBlocks); + if (block instanceof IHaveConnectedTextures) + swapModels(modelRegistry, blockModelLocations, t -> new CTModel(t, (IHaveConnectedTextures) block)); + if (block instanceof IBlockWithColoredVertices) + swapModels(modelRegistry, blockModelLocations, + t -> new ColoredVertexModel(t, (IBlockWithColoredVertices) block)); + } swapModels(modelRegistry, getItemModelLocation(AllItems.SYMMETRY_WAND), @@ -151,10 +166,21 @@ public class CreateClient { ModelLoader.addSpecialModel(new ResourceLocation(Create.ID, "item/" + location)); } + @OnlyIn(Dist.CLIENT) protected static ModelResourceLocation getItemModelLocation(AllItems item) { return new ModelResourceLocation(item.item.getRegistryName(), "inventory"); } + @OnlyIn(Dist.CLIENT) + protected static List getAllBlockStateModelLocations(AllBlocks block) { + List models = new ArrayList<>(); + block.get().getStateContainer().getValidStates().forEach(state -> { + models.add(getBlockModelLocation(block, BlockModelShapes.getPropertyMapString(state.getValues()))); + }); + return models; + } + + @OnlyIn(Dist.CLIENT) protected static ModelResourceLocation getBlockModelLocation(AllBlocks block, String suffix) { return new ModelResourceLocation(block.block.getRegistryName(), suffix); } @@ -165,4 +191,12 @@ public class CreateClient { modelRegistry.put(location, factory.apply(modelRegistry.get(location))); } + @OnlyIn(Dist.CLIENT) + protected static void swapModels(Map modelRegistry, + List locations, Function factory) { + locations.forEach(location -> { + swapModels(modelRegistry, location, factory); + }); + } + } diff --git a/src/main/java/com/simibubi/create/CreateConfig.java b/src/main/java/com/simibubi/create/CreateConfig.java index ff1a88154..4cb1c2fbc 100644 --- a/src/main/java/com/simibubi/create/CreateConfig.java +++ b/src/main/java/com/simibubi/create/CreateConfig.java @@ -164,8 +164,8 @@ public class CreateConfig { .translation(basePath + name).defineInRange(name, 20, 1, Integer.MAX_VALUE); name = "extractorInventoryScanDelay"; - extractorInventoryScanDelay = builder - .comment("", "The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.") + extractorInventoryScanDelay = builder.comment("", + "The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.") .translation(basePath + name).defineInRange(name, 40, 1, Integer.MAX_VALUE); name = "extractorAmount"; @@ -348,7 +348,7 @@ public class CreateConfig { .translation(basePath + name).defineInRange(name, 32D, 0D, 4096D); name = "fastSpeed"; - mediumSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'fast'") + fastSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'fast'") .translation(basePath + name).defineInRange(name, 512D, 0D, 65535D); name = "mediumStressImpact"; diff --git a/src/main/java/com/simibubi/create/ResourceReloadHandler.java b/src/main/java/com/simibubi/create/ResourceReloadHandler.java index e605bc049..be9478bab 100644 --- a/src/main/java/com/simibubi/create/ResourceReloadHandler.java +++ b/src/main/java/com/simibubi/create/ResourceReloadHandler.java @@ -1,7 +1,7 @@ package com.simibubi.create; import com.simibubi.create.foundation.block.SpriteShifter; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer; +import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntityRenderer; import net.minecraft.client.resources.ReloadListener; import net.minecraft.profiler.IProfiler; diff --git a/src/main/java/com/simibubi/create/foundation/block/CTModel.java b/src/main/java/com/simibubi/create/foundation/block/CTModel.java index af98a8865..9ea1a01c6 100644 --- a/src/main/java/com/simibubi/create/foundation/block/CTModel.java +++ b/src/main/java/com/simibubi/create/foundation/block/CTModel.java @@ -24,7 +24,7 @@ import net.minecraftforge.client.model.data.ModelProperty; public class CTModel extends BakedModelWrapper { private static ModelProperty CT_PROPERTY = new ModelProperty<>(); - private SpriteShiftEntry texture; + private Iterable textures; private class CTData { int[] textures; @@ -43,9 +43,9 @@ public class CTModel extends BakedModelWrapper { } } - public CTModel(IBakedModel originalModel, String blockId) { + public CTModel(IBakedModel originalModel, IHaveConnectedTextures block) { super(originalModel); - texture = SpriteShifter.getCT(blockId); + textures = block.getSpriteShifts(); } @Override @@ -74,9 +74,20 @@ public class CTModel extends BakedModelWrapper { BakedQuad quad = quads.get(i); if (!texDef.appliesTo(quad)) continue; + + SpriteShiftEntry texture = null; + for (SpriteShiftEntry entry : textures) { + if (entry.getOriginal() == quad.getSprite()) { + texture = entry; + break; + } + } + if (texture == null) + continue; + int index = data.get(quad.getFace()); if (index == -1) - return quads; + continue; float textureSize = 16f / 128f / 8f; float uShift = (index % 8) * textureSize; diff --git a/src/main/java/com/simibubi/create/foundation/block/ColoredVertexModel.java b/src/main/java/com/simibubi/create/foundation/block/ColoredVertexModel.java new file mode 100644 index 000000000..1a19e2598 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/ColoredVertexModel.java @@ -0,0 +1,71 @@ +package com.simibubi.create.foundation.block; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import net.minecraft.block.BlockState; +import net.minecraft.client.renderer.model.BakedQuad; +import net.minecraft.client.renderer.model.IBakedModel; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IEnviromentBlockReader; +import net.minecraftforge.client.model.BakedModelWrapper; +import net.minecraftforge.client.model.data.IModelData; +import net.minecraftforge.client.model.data.ModelDataMap; +import net.minecraftforge.client.model.data.ModelProperty; + +public class ColoredVertexModel extends BakedModelWrapper { + + private IBlockWithColoredVertices colorer; + private static ModelProperty POSITION_PROPERTY = new ModelProperty<>(); + + public ColoredVertexModel(IBakedModel originalModel, IBlockWithColoredVertices colorer) { + super(originalModel); + this.colorer = colorer; + } + + @Override + public IModelData getModelData(IEnviromentBlockReader world, BlockPos pos, BlockState state, IModelData tileData) { + return new ModelDataMap.Builder().withInitial(POSITION_PROPERTY, pos).build(); + } + + @Override + public List getQuads(BlockState state, Direction side, Random rand, IModelData extraData) { + List quads = new ArrayList<>(super.getQuads(state, side, rand, extraData)); + + if (!extraData.hasProperty(POSITION_PROPERTY)) + return quads; + + for (int i = 0; i < quads.size(); i++) { + BakedQuad quad = quads.get(i); + + BakedQuad newQuad = new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), + quad.getTintIndex(), quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting(), + quad.getFormat()); + + VertexFormat format = quad.getFormat(); + int[] vertexData = newQuad.getVertexData(); + BlockPos data = extraData.getData(POSITION_PROPERTY); + +// Direction direction = quad.getFace(); +// if (direction.getAxis().isHorizontal()) +// continue; + + for (int vertex = 0; vertex < vertexData.length; vertex += format.getIntegerSize()) { + int colorOffset = format.getColorOffset() / 4; + float x = Float.intBitsToFloat(vertexData[vertex]); + float y = Float.intBitsToFloat(vertexData[vertex + 1]); + float z = Float.intBitsToFloat(vertexData[vertex + 2]); + int color = colorer.getColor(x + data.getX(), y + data.getY(), z + data.getZ()); + vertexData[vertex + colorOffset] = color; + } + + quads.set(i, newQuad); + } + return quads; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/IBlockWithColoredVertices.java b/src/main/java/com/simibubi/create/foundation/block/IBlockWithColoredVertices.java new file mode 100644 index 000000000..d1fbe7645 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/IBlockWithColoredVertices.java @@ -0,0 +1,7 @@ +package com.simibubi.create.foundation.block; + +public interface IBlockWithColoredVertices { + + public int getColor(float x, float y, float z); + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/IHaveConnectedTextures.java b/src/main/java/com/simibubi/create/foundation/block/IHaveConnectedTextures.java index 534accb8b..300aec369 100644 --- a/src/main/java/com/simibubi/create/foundation/block/IHaveConnectedTextures.java +++ b/src/main/java/com/simibubi/create/foundation/block/IHaveConnectedTextures.java @@ -2,6 +2,10 @@ package com.simibubi.create.foundation.block; import java.util.function.BiPredicate; +import com.google.common.collect.ImmutableList; +import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry; + +import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.util.Direction; @@ -20,7 +24,9 @@ public interface IHaveConnectedTextures { } @OnlyIn(Dist.CLIENT) - public boolean appliesTo(BakedQuad quad); + default boolean appliesTo(BakedQuad quad) { + return true; + } default boolean connectsTo(BlockState state, BlockState other, IEnviromentBlockReader reader, BlockPos pos, BlockPos otherPos, Direction face) { @@ -34,6 +40,10 @@ public interface IHaveConnectedTextures { return state.getBlock() == other.getBlock(); } + default Iterable getSpriteShifts() { + return ImmutableList.of(SpriteShifter.getCT(((Block) this).getRegistryName().getPath())); + } + default int getTextureIndex(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face) { return getTextureIndexForContext(reader, pos, state, face, buildContext(reader, pos, state, face)); } @@ -57,18 +67,34 @@ public interface IHaveConnectedTextures { return connectsTo(state, reader.getBlockState(p), reader, pos, p, face); }; + boolean up = connection.test(0, 1); + boolean down = connection.test(0, -1); + boolean left = connection.test(-1, 0); + boolean right = connection.test(1, 0); + boolean topLeft = connection.test(-1, 1); + boolean topRight = connection.test(1, 1); + boolean bottomLeft = connection.test(-1, -1); + boolean bottomRight = connection.test(1, -1); + + boolean flip = shouldFlipUVs(state, face); CTContext context = new CTContext(); - context.up = connection.test(0, 1); - context.down = connection.test(0, -1); - context.left = connection.test(-1, 0); - context.right = connection.test(1, 0); - context.topLeft = connection.test(-1, 1); - context.topRight = connection.test(1, 1); - context.bottomLeft = connection.test(-1, -1); - context.bottomRight = connection.test(1, -1); + + context.up = flip ? down : up; + context.down = flip ? up : down; + context.left = flip ? right : left; + context.right = flip ? left : right; + context.topLeft = flip ? bottomRight : topLeft; + context.topRight = flip ? bottomLeft : topRight; + context.bottomLeft = flip ? topRight : bottomLeft; + context.bottomRight = flip ? topLeft : bottomRight; + return context; } + default boolean shouldFlipUVs(BlockState state, Direction face) { + return false; + } + default int getTextureIndexForContext(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face, CTContext c) { int tileX = 0, tileY = 0; diff --git a/src/main/java/com/simibubi/create/foundation/block/SpriteShifter.java b/src/main/java/com/simibubi/create/foundation/block/SpriteShifter.java index 56d775288..180a51887 100644 --- a/src/main/java/com/simibubi/create/foundation/block/SpriteShifter.java +++ b/src/main/java/com/simibubi/create/foundation/block/SpriteShifter.java @@ -24,11 +24,19 @@ public class SpriteShifter { target = textureMap.getSprite(targetTextureLocation); } + public ResourceLocation getTargetResourceLocation() { + return targetTextureLocation; + } + public TextureAtlasSprite getTarget() { + if (target == null) + loadTextures(); return target; } public TextureAtlasSprite getOriginal() { + if (original == null) + loadTextures(); return original; } } @@ -47,7 +55,6 @@ public class SpriteShifter { SpriteShiftEntry entry = new SpriteShiftEntry(); entry.originalTextureLocation = new ResourceLocation(Create.ID, originalLocation); entry.targetTextureLocation = new ResourceLocation(Create.ID, targetLocation); - entry.loadTextures(); textures.put(key, entry); return entry; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/GogglesItem.java b/src/main/java/com/simibubi/create/modules/contraptions/GogglesItem.java new file mode 100644 index 000000000..bb7835fed --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/GogglesItem.java @@ -0,0 +1,49 @@ +package com.simibubi.create.modules.contraptions; + +import com.simibubi.create.AllItems; + +import net.minecraft.block.DispenserBlock; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.world.World; + +public class GogglesItem extends Item { + + public GogglesItem(Properties properties) { + super(properties); + DispenserBlock.registerDispenseBehavior(this, ArmorItem.DISPENSER_BEHAVIOR); + } + + @Override + public EquipmentSlotType getEquipmentSlot(ItemStack stack) { + return EquipmentSlotType.HEAD; + } + + public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { + ItemStack itemstack = playerIn.getHeldItem(handIn); + EquipmentSlotType equipmentslottype = MobEntity.getSlotForItemStack(itemstack); + ItemStack itemstack1 = playerIn.getItemStackFromSlot(equipmentslottype); + if (itemstack1.isEmpty()) { + playerIn.setItemStackToSlot(equipmentslottype, itemstack.copy()); + itemstack.setCount(0); + return new ActionResult<>(ActionResultType.SUCCESS, itemstack); + } else { + return new ActionResult<>(ActionResultType.FAIL, itemstack); + } + } + + public static boolean canSeeParticles(PlayerEntity player) { + for (ItemStack itemStack : player.getArmorInventoryList()) + if (AllItems.GOGGLES.typeOf(itemStack)) + return true; + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java index 2fef619b8..ffc3b77fe 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java @@ -3,6 +3,8 @@ package com.simibubi.create.modules.contraptions.base; import java.util.Optional; import java.util.UUID; +import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; + import net.minecraft.tileentity.TileEntityType; public abstract class GeneratingKineticTileEntity extends KineticTileEntity { @@ -24,6 +26,14 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { float speed = getGeneratedSpeed(); if (this.speed != speed) { + + if (!world.isRemote) { + SpeedLevel levelBefore = SpeedLevel.of(this.speed); + SpeedLevel levelafter = SpeedLevel.of(speed); + if (levelBefore != levelafter) + queueRotationIndicators(); + } + if (speed == 0) { if (hasSource()) notifyStressCapacityChange(0); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/IRotate.java b/src/main/java/com/simibubi/create/modules/contraptions/base/IRotate.java index 1f87a3950..70cae5715 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/IRotate.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/IRotate.java @@ -1,5 +1,7 @@ package com.simibubi.create.modules.contraptions.base; +import com.simibubi.create.CreateConfig; + import net.minecraft.block.BlockState; import net.minecraft.item.ItemUseContext; import net.minecraft.util.ActionResultType; @@ -18,6 +20,17 @@ public interface IRotate { return this == NONE ? TextFormatting.GREEN : this == MEDIUM ? TextFormatting.AQUA : TextFormatting.LIGHT_PURPLE; } + + public static SpeedLevel of(float speed) { + speed = Math.abs(speed); + + if (speed >= CreateConfig.parameters.fastSpeed.get()) { + return FAST; + } else if (speed >= CreateConfig.parameters.mediumSpeed.get()) { + return MEDIUM; + } + return NONE; + } } public enum StressImpact { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java index 285519ac7..b95e1ef3d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java @@ -6,6 +6,8 @@ import com.simibubi.create.modules.contraptions.RotationPropagator; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.material.PushReaction; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; @@ -79,4 +81,24 @@ public abstract class KineticBlock extends Block implements IRotate { return false; } + @Override + public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + TileEntity tileEntity = worldIn.getTileEntity(pos); + if (tileEntity == null || !(tileEntity instanceof KineticTileEntity)) + return; + if (worldIn.isRemote) + return; + + KineticTileEntity kte = (KineticTileEntity) tileEntity; + kte.queueRotationIndicators(); + } + + public float getParticleTargetRadius() { + return .65f; + } + + public float getParticleInitialRadius() { + return .75f; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index 408c7f029..beac04ca5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -12,10 +12,13 @@ import java.util.UUID; import com.simibubi.create.Create; import com.simibubi.create.CreateConfig; import com.simibubi.create.foundation.block.SyncedTileEntity; +import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.RotationPropagator; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; +import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; @@ -24,11 +27,16 @@ import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.ForgeConfigSpec.DoubleValue; public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity { + int particleSpawnCountdown; + // Speed related public float speed; protected Optional source; @@ -254,6 +262,10 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic if (world.isRemote) return; + if (particleSpawnCountdown > 0) + if (--particleSpawnCountdown == 0) + spawnRotationIndicators(); + if (initNetwork) { initNetwork = false; @@ -310,4 +322,53 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress); } + public void queueRotationIndicators() { + // wait a few ticks for network jamming etc + particleSpawnCountdown = 2; + } + + protected void spawnRotationIndicators() { + if (getSpeed() == 0) + return; + + BlockState state = getBlockState(); + Block block = state.getBlock(); + if (!(block instanceof KineticBlock)) + return; + + KineticBlock kb = (KineticBlock) block; + float radius1 = kb.getParticleInitialRadius(); + float radius2 = kb.getParticleTargetRadius(); + + Axis axis = kb.getRotationAxis(state); + if (axis == null) + return; + char axisChar = axis.name().charAt(0); + Vec3d vec = VecHelper.getCenterOf(pos); + + int color = 0x22FF22; + int particleSpeed = 10; + + switch (SpeedLevel.of(getSpeed())) { + case FAST: + color = 16733695; + particleSpeed = 30; + break; + case MEDIUM: + color = 0x0084FF; + particleSpeed = 20; + break; + default: + break; + } + + particleSpeed *= Math.signum(getSpeed()); + + if (getWorld() instanceof ServerWorld) { + RotationIndicatorParticleData particleData = new RotationIndicatorParticleData(color, particleSpeed, + radius1, radius2, 10, axisChar); + ((ServerWorld) getWorld()).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1); + } + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java index c4e65ba9e..51bdb9c90 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java @@ -134,4 +134,14 @@ public class WaterWheelBlock extends HorizontalKineticBlock { return state.get(HORIZONTAL_FACING).getAxis(); } + @Override + public float getParticleTargetRadius() { + return 1.125f; + } + + @Override + public float getParticleInitialRadius() { + return 1f; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java new file mode 100644 index 000000000..051a1ec00 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java @@ -0,0 +1,102 @@ +package com.simibubi.create.modules.contraptions.particle; + +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.GogglesItem; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.particle.IAnimatedSprite; +import net.minecraft.client.particle.IParticleFactory; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class RotationIndicatorParticle extends SimpleAnimatedParticle { + + protected float radius; + protected float radius1; + protected float radius2; + protected float speed; + protected Axis axis; + protected Vec3d origin; + protected Vec3d offset; + protected boolean isVisible; + + private RotationIndicatorParticle(World world, double x, double y, double z, int color, float radius1, + float radius2, float speed, Axis axis, int lifeSpan, boolean isVisible, IAnimatedSprite sprite) { + super(world, x, y, z, sprite, 0); + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; + this.origin = new Vec3d(x, y, z); + this.particleScale *= 0.75F; + this.maxAge = lifeSpan + this.rand.nextInt(32); + this.setColorFade(color); + this.setColor(ColorHelper.mixColors(color, 0xFFFFFF, .5f)); + this.selectSpriteWithAge(sprite); + this.radius1 = radius1; + this.radius = radius1; + this.radius2 = radius2; + this.speed = speed; + this.axis = axis; + this.isVisible = isVisible; + this.offset = axis.isHorizontal() ? new Vec3d(0, 1, 0) : new Vec3d(1, 0, 0); + move(0, 0, 0); + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + } + + @Override + public void tick() { + super.tick(); + radius += (radius2 - radius) * .1f; + } + + @Override + public void renderParticle(BufferBuilder buffer, ActiveRenderInfo entityIn, float partialTicks, float rotationX, + float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + if (!isVisible) + return; + super.renderParticle(buffer, entityIn, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + } + + public void move(double x, double y, double z) { + float time = AnimationTickHolder.ticks; + float angle = (float) ((time * speed) % 360) - (speed / 2 * age * (((float) age) / maxAge)); + Vec3d position = VecHelper.rotate(this.offset.scale(radius), angle, axis).add(origin); + posX = position.x; + posY = position.y; + posZ = position.z; + } + + public static class Type extends ParticleType { + public Type() { + super(false, RotationIndicatorParticleData.DESERIALIZER); + } + } + + public static class Factory implements IParticleFactory { + private final IAnimatedSprite spriteSet; + + public Factory(IAnimatedSprite animatedSprite) { + this.spriteSet = animatedSprite; + } + + public Particle makeParticle(RotationIndicatorParticleData data, World worldIn, double x, double y, double z, + double xSpeed, double ySpeed, double zSpeed) { + ClientPlayerEntity player = Minecraft.getInstance().player; + boolean visible = player != null && GogglesItem.canSeeParticles(player); + return new RotationIndicatorParticle(worldIn, x, y, z, data.color, data.radius1, data.radius2, data.speed, + data.getAxis(), data.lifeSpan, visible, this.spriteSet); + } + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticleData.java b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticleData.java new file mode 100644 index 000000000..4c6c33b35 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticleData.java @@ -0,0 +1,82 @@ +package com.simibubi.create.modules.contraptions.particle; + +import java.util.Locale; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.simibubi.create.AllParticles; + +import net.minecraft.network.PacketBuffer; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleType; +import net.minecraft.util.Direction.Axis; + +public class RotationIndicatorParticleData implements IParticleData { + + public static final IParticleData.IDeserializer DESERIALIZER = new IParticleData.IDeserializer() { + public RotationIndicatorParticleData deserialize(ParticleType particleTypeIn, + StringReader reader) throws CommandSyntaxException { + reader.expect(' '); + int color = reader.readInt(); + reader.expect(' '); + float speed = (float) reader.readDouble(); + reader.expect(' '); + float rad1 = (float) reader.readDouble(); + reader.expect(' '); + float rad2 = (float) reader.readDouble(); + reader.expect(' '); + int lifeSpan = reader.readInt(); + reader.expect(' '); + char axis = reader.read(); + return new RotationIndicatorParticleData(color, speed, rad1, rad2, lifeSpan, axis); + } + + public RotationIndicatorParticleData read(ParticleType particleTypeIn, + PacketBuffer buffer) { + return new RotationIndicatorParticleData(buffer.readInt(), buffer.readFloat(), buffer.readFloat(), + buffer.readFloat(), buffer.readInt(), buffer.readChar()); + } + }; + + final int color; + final float speed; + final float radius1; + final float radius2; + final int lifeSpan; + final char axis; + + public RotationIndicatorParticleData(int color, float speed, float radius1, float radius2, int lifeSpan, + char axis) { + this.color = color; + this.speed = speed; + this.radius1 = radius1; + this.radius2 = radius2; + this.lifeSpan = lifeSpan; + this.axis = axis; + } + + @Override + public ParticleType getType() { + return AllParticles.ROTATION_INDICATOR.get(); + } + + public Axis getAxis() { + return Axis.valueOf(axis + ""); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(color); + buffer.writeFloat(speed); + buffer.writeFloat(radius1); + buffer.writeFloat(radius2); + buffer.writeInt(lifeSpan); + } + + @Override + public String getParameters() { + return String.format(Locale.ROOT, "%s %d %.2f %.2f %.2f %d %c", AllParticles.ROTATION_INDICATOR.parameter(), + color, speed, radius1, radius2, lifeSpan, axis); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelBlock.java index fdf78b7a6..a20ccd553 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelBlock.java @@ -167,5 +167,15 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock { protected boolean hasStaticPart() { return false; } + + @Override + public float getParticleTargetRadius() { + return 1.125f; + } + + @Override + public float getParticleInitialRadius() { + return 1f; + } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerBlock.java index 63528c02f..af2cdac9e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerBlock.java @@ -133,6 +133,16 @@ public class MechanicalMixerBlock extends KineticBlock return tileEntity.currentValue; } + @Override + public float getParticleTargetRadius() { + return .85f; + } + + @Override + public float getParticleInitialRadius() { + return .75f; + } + @Override public SpeedLevel getMinimumRequiredSpeedLevel() { return SpeedLevel.MEDIUM; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/Contraption.java index 803488188..50a2019c5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/Contraption.java @@ -43,9 +43,9 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; public class Contraption { - protected Map blocks; - protected List> actors; - protected AxisAlignedBB constructCollisionBox; + public Map blocks; + public List> actors; + public AxisAlignedBB constructCollisionBox; protected Set cachedColliders; protected Direction cachedColliderDirection; protected BlockPos anchor; @@ -74,9 +74,9 @@ public class Contraption { return null; BlockState state = world.getBlockState(current); - if (!isChassis(state)) + if (!isLinearChassis(state)) continue; - if (!TranslationChassisBlock.sameKind(anchorChassis, state)) + if (!LinearChassisBlock.sameKind(anchorChassis, state)) continue; if (state.get(AXIS) != axis) continue; @@ -157,8 +157,11 @@ public class Contraption { return true; if (!canPush(world, pos, direction)) return false; - if (isChassis(state) && !moveChassis(world, pos, direction, frontier, visited)) + if (isLinearChassis(state) && !moveLinearChassis(world, pos, direction, frontier, visited)) return false; + if (isRadialChassis(state) && !moveRadialChassis(world, pos, direction, frontier, visited)) + return false; + if (state.getBlock() instanceof SlimeBlock) for (Direction offset : Direction.values()) { BlockPos offsetPos = pos.offset(offset); @@ -177,7 +180,7 @@ public class Contraption { return true; } - private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List frontier, + private boolean moveLinearChassis(World world, BlockPos pos, Direction movementDirection, List frontier, Set visited) { List cluster = getChassisClusterAt(world, pos); @@ -223,7 +226,7 @@ public class Contraption { BlockState chassisState = world.getBlockState(currentChassisPos); // Not attached to a chassis - if (!isChassis(chassisState) || chassisState.get(AXIS) != chassisAxis) + if (!isLinearChassis(chassisState) || chassisState.get(AXIS) != chassisAxis) continue; if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == chassisDirection.getOpposite()) @@ -300,8 +303,96 @@ public class Contraption { return true; } - private static boolean isChassis(BlockState state) { - return TranslationChassisBlock.isChassis(state); + private boolean moveRadialChassis(World world, BlockPos pos, Direction movementDirection, List frontier, + Set visited) { + RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block; + + List chassisPositions = new ArrayList<>(); + BlockState chassisState = world.getBlockState(pos); + Axis axis = chassisState.get(RadialChassisBlock.AXIS); + chassisPositions.add(pos); + + // Collect chain of chassis + for (int offset : new int[] { -1, 1 }) { + for (int distance = 1; distance <= parameters.maxChassisForTranslation.get(); distance++) { + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + BlockPos currentPos = pos.offset(direction, distance * offset); + if (!world.isBlockPresent(currentPos)) + return false; + + BlockState state = world.getBlockState(currentPos); + if (!AllBlocks.ROTATION_CHASSIS.typeOf(state)) + break; + if (direction.getAxis() != state.get(BlockStateProperties.AXIS)) + break; + + chassisPositions.add(currentPos); + } + } + + // Add attached blocks to frontier + for (BlockPos chassisPos : chassisPositions) { + add(chassisPos, capture(world, chassisPos)); + visited.add(chassisPos); + + BlockPos currentPos = chassisPos; + BlockState state = world.getBlockState(currentPos); + TileEntity tileEntity = world.getTileEntity(currentPos); + + if (!(tileEntity instanceof ChassisTileEntity)) + return false; + + int chassisRange = ((ChassisTileEntity) tileEntity).getRange(); + + for (Direction facing : Direction.values()) { + if (facing.getAxis() == axis) + continue; + if (!state.get(def.getGlueableSide(state, facing))) + continue; + + BlockPos startPos = currentPos.offset(facing); + List localFrontier = new LinkedList<>(); + Set localVisited = new HashSet<>(); + localFrontier.add(startPos); + + while (!localFrontier.isEmpty()) { + BlockPos searchPos = localFrontier.remove(0); + BlockState searchedState = world.getBlockState(searchPos); + + if (localVisited.contains(searchPos)) + continue; + if (!searchPos.withinDistance(currentPos, chassisRange + .5f)) + continue; + if (searchedState.getMaterial().isReplaceable() || state.isAir(world, searchPos)) + continue; + if (searchedState.getCollisionShape(world, searchPos).isEmpty()) + continue; + + localVisited.add(searchPos); + if (!visited.contains(searchPos)) + frontier.add(searchPos); + + for (Direction offset : Direction.values()) { + if (offset.getAxis() == axis) + continue; + if (searchPos.equals(currentPos) && offset != facing) + continue; + + localFrontier.add(searchPos.offset(offset)); + } + } + } + } + + return true; + } + + private static boolean isLinearChassis(BlockState state) { + return LinearChassisBlock.isChassis(state); + } + + private static boolean isRadialChassis(BlockState state) { + return AllBlocks.ROTATION_CHASSIS.typeOf(state); } private boolean notSupportive(World world, BlockPos pos, Direction facing) { @@ -315,7 +406,7 @@ public class Contraption { protected static boolean canPush(World world, BlockPos pos, Direction direction) { BlockState blockState = world.getBlockState(pos); - if (isChassis(blockState)) + if (isLinearChassis(blockState) || isRadialChassis(blockState)) return true; if (blockState.getBlock() instanceof ShulkerBoxBlock) return false; @@ -365,7 +456,7 @@ public class Contraption { MovementContext context = MovementContext.readNBT(comp); getActors().add(MutablePair.of(info, context)); }); - + if (nbt.contains("BoundsFront")) constructCollisionBox = readAABB(nbt.getList("BoundsFront", 5)); @@ -387,7 +478,7 @@ public class Contraption { c.put("Data", block.nbt); blocks.add(c); } - + ListNBT actorsNBT = new ListNBT(); for (MutablePair actor : getActors()) { CompoundNBT compound = new CompoundNBT(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/IHaveMovementBehavior.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/IHaveMovementBehavior.java index 9f45281e1..50362a879 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/IHaveMovementBehavior.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/IHaveMovementBehavior.java @@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.receivers.constructs; import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonTileEntity; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/TranslationChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/LinearChassisBlock.java similarity index 64% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/TranslationChassisBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/LinearChassisBlock.java index 5dd66b942..5eecafc86 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/TranslationChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/LinearChassisBlock.java @@ -1,6 +1,10 @@ package com.simibubi.create.modules.contraptions.receivers.constructs; +import com.google.common.collect.ImmutableList; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.block.IHaveConnectedTextures; +import com.simibubi.create.foundation.block.SpriteShifter; +import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -11,13 +15,14 @@ import net.minecraft.state.StateContainer.Builder; import net.minecraft.util.Direction; import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IEnviromentBlockReader; -public class TranslationChassisBlock extends AbstractChassisBlock { +public class LinearChassisBlock extends AbstractChassisBlock implements IHaveConnectedTextures { public static final BooleanProperty STICKY_TOP = BooleanProperty.create("sticky_top"); public static final BooleanProperty STICKY_BOTTOM = BooleanProperty.create("sticky_bottom"); - public TranslationChassisBlock() { + public LinearChassisBlock() { super(Properties.from(Blocks.PISTON)); setDefaultState(getDefaultState().with(STICKY_TOP, false).with(STICKY_BOTTOM, false)); } @@ -45,7 +50,7 @@ public class TranslationChassisBlock extends AbstractChassisBlock { return null; return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM; } - + @Override public String getTranslationKey() { Block block = AllBlocks.TRANSLATION_CHASSIS.get(); @@ -62,4 +67,25 @@ public class TranslationChassisBlock extends AbstractChassisBlock { return state1.getBlock() == state2.getBlock(); } + @Override + public Iterable getSpriteShifts() { + return ImmutableList.of( + SpriteShifter.get("block/translation_chassis_top", "block/connected/translation_chassis_top"), + SpriteShifter.get("block/translation_chassis_top_sticky", + "block/connected/translation_chassis_top_sticky")); + } + + @Override + public boolean shouldFlipUVs(BlockState state, Direction face) { + if (state.get(AXIS).isHorizontal() && face.getAxisDirection() == AxisDirection.POSITIVE) + return true; + return IHaveConnectedTextures.super.shouldFlipUVs(state, face); + } + + @Override + public boolean connectsTo(BlockState state, BlockState other, IEnviromentBlockReader reader, BlockPos pos, + BlockPos otherPos, Direction face) { + return sameKind(state, other) && state.get(AXIS) == other.get(AXIS); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RadialChassisBlock.java similarity index 95% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationChassisBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RadialChassisBlock.java index b4098ac30..38f54cd56 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RadialChassisBlock.java @@ -12,14 +12,14 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; -public class RotationChassisBlock extends AbstractChassisBlock { +public class RadialChassisBlock extends AbstractChassisBlock { public static final BooleanProperty STICKY_NORTH = BooleanProperty.create("sticky_north"); public static final BooleanProperty STICKY_SOUTH = BooleanProperty.create("sticky_south"); public static final BooleanProperty STICKY_EAST = BooleanProperty.create("sticky_east"); public static final BooleanProperty STICKY_WEST = BooleanProperty.create("sticky_west"); - public RotationChassisBlock() { + public RadialChassisBlock() { super(Properties.from(Blocks.PISTON)); setDefaultState(getDefaultState().with(STICKY_EAST, false).with(STICKY_SOUTH, false).with(STICKY_NORTH, false) .with(STICKY_WEST, false)); @@ -30,16 +30,16 @@ public class RotationChassisBlock extends AbstractChassisBlock { builder.add(STICKY_NORTH, STICKY_EAST, STICKY_SOUTH, STICKY_WEST); super.fillStateContainer(builder); } - + @Override public String getValueName(BlockState state, IWorld world, BlockPos pos) { return Lang.translate("generic.radius"); } - + @Override public BooleanProperty getGlueableSide(BlockState state, Direction face) { Axis axis = state.get(AXIS); - + if (axis == Axis.X) { if (face == Direction.NORTH) return STICKY_WEST; @@ -50,7 +50,7 @@ public class RotationChassisBlock extends AbstractChassisBlock { if (face == Direction.DOWN) return STICKY_SOUTH; } - + if (axis == Axis.Y) { if (face == Direction.NORTH) return STICKY_NORTH; @@ -61,7 +61,7 @@ public class RotationChassisBlock extends AbstractChassisBlock { if (face == Direction.WEST) return STICKY_WEST; } - + if (axis == Axis.Z) { if (face == Direction.UP) return STICKY_NORTH; @@ -72,7 +72,7 @@ public class RotationChassisBlock extends AbstractChassisBlock { if (face == Direction.WEST) return STICKY_WEST; } - + return null; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingBlock.java similarity index 99% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingBlock.java index 59aae4b03..62ae7d5d0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingBlock.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.bearing; import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntity.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntity.java index b1d481dbc..d1c6f969c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntity.java @@ -1,7 +1,8 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.bearing; import com.simibubi.create.AllTileEntities; import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisTileEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntityRenderer.java similarity index 99% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntityRenderer.java index c322a955a..96e4f5dcf 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/MechanicalBearingTileEntityRenderer.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.bearing; import java.util.Random; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstruct.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstruct.java similarity index 95% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstruct.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstruct.java index 2435c27c6..6df9082d2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstruct.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstruct.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.bearing; import java.util.ArrayList; import java.util.HashMap; @@ -11,6 +11,8 @@ import java.util.Set; import com.simibubi.create.AllBlockTags; import com.simibubi.create.AllBlocks; import com.simibubi.create.CreateConfig; +import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisTileEntity; +import com.simibubi.create.modules.contraptions.receivers.constructs.RadialChassisBlock; import net.minecraft.block.BlockState; import net.minecraft.block.PistonBlock; @@ -87,7 +89,7 @@ public class RotationConstruct { private List getAttachedBlocksByChassis(World world, Direction direction, List chassis) { List blocks = new ArrayList<>(); - RotationChassisBlock def = (RotationChassisBlock) AllBlocks.ROTATION_CHASSIS.block; + RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block; for (BlockInfo chassisBlock : chassis) { blocks.add(chassisBlock); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstructVertexBuffer.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstructVertexBuffer.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstructVertexBuffer.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstructVertexBuffer.java index a99f50a58..f2b459bd6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/RotationConstructVertexBuffer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/bearing/RotationConstructVertexBuffer.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.bearing; import java.nio.ByteBuffer; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/mounted/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/mounted/ContraptionEntity.java index e1d336cab..8e0f635ad 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/mounted/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/mounted/ContraptionEntity.java @@ -25,6 +25,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected MountedContraption contraption; protected float initialAngle; + + enum MovementType { + TRANSLATION, ROTATION, MOUNTED; + } // Not synchronizing any of these public float targetYaw; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonBlock.java similarity index 99% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonBlock.java index c61a47ce3..6dcf88bcb 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonBlock.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import com.simibubi.create.AllBlocks; import com.simibubi.create.CreateConfig; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonHeadBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonHeadBlock.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonHeadBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonHeadBlock.java index 132a66335..549b35823 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonHeadBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonHeadBlock.java @@ -1,10 +1,10 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import com.simibubi.create.AllBlocks; import com.simibubi.create.CreateConfig; import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.ProperDirectionalBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState; import net.minecraft.block.Block; import net.minecraft.block.BlockState; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntity.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntity.java index 6ff49a4c3..16af39596 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntity.java @@ -1,7 +1,7 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import static com.simibubi.create.CreateConfig.parameters; -import static com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.STATE; +import static com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.STATE; import java.util.Arrays; import java.util.Iterator; @@ -12,9 +12,10 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.Create; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior; import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext; import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MoverType; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState; import net.minecraft.block.Blocks; import net.minecraft.nbt.CompoundNBT; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntityRenderer.java similarity index 93% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntityRenderer.java index 7eaad36be..31c31eefb 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MechanicalPistonTileEntityRenderer.java @@ -1,9 +1,10 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import com.simibubi.create.AllBlocks; import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.BufferBuilder; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MovingConstructHandler.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MovingConstructHandler.java index fc6904906..f45d13375 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/MovingConstructHandler.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import java.util.ArrayList; import java.util.HashMap; @@ -8,6 +8,7 @@ import java.util.Map; import java.util.stream.Stream; import com.simibubi.create.Create; +import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption; import net.minecraft.block.material.PushReaction; import net.minecraft.entity.Entity; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonContraption.java similarity index 97% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonContraption.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonContraption.java index 29a406ce9..c5a0c3ed2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonContraption.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; import static com.simibubi.create.AllBlocks.PISTON_POLE; @@ -10,7 +10,8 @@ import java.util.ArrayList; import java.util.List; import com.simibubi.create.AllBlocks; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; +import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonPoleBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonPoleBlock.java similarity index 98% rename from src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonPoleBlock.java rename to src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonPoleBlock.java index 0df3d5d55..5a9cbb1be 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/PistonPoleBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/piston/PistonPoleBlock.java @@ -1,9 +1,9 @@ -package com.simibubi.create.modules.contraptions.receivers.constructs; +package com.simibubi.create.modules.contraptions.receivers.constructs.piston; import com.simibubi.create.AllBlocks; import com.simibubi.create.CreateConfig; import com.simibubi.create.foundation.block.ProperDirectionalBlock; -import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState; +import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -22,7 +22,6 @@ import net.minecraft.world.World; public class PistonPoleBlock extends ProperDirectionalBlock { - public PistonPoleBlock() { super(Properties.from(Blocks.PISTON_HEAD)); setDefaultState(getDefaultState().with(FACING, Direction.UP)); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/crafter/MechanicalCrafterBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/crafter/MechanicalCrafterBlock.java index 8cb6ad7f3..b6fc7c964 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/crafter/MechanicalCrafterBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/crafter/MechanicalCrafterBlock.java @@ -40,7 +40,7 @@ public class MechanicalCrafterBlock extends DirectionalKineticBlock public Axis getRotationAxis(BlockState state) { return state.get(FACING).getAxis(); } - + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite()); @@ -49,10 +49,20 @@ public class MechanicalCrafterBlock extends DirectionalKineticBlock return getDefaultState().with(FACING, blockState.get(FACING)); return super.getStateForPlacement(context); } - + @Override public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT_MIPPED; } + @Override + public float getParticleTargetRadius() { + return .85f; + } + + @Override + public float getParticleInitialRadius() { + return .75f; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/CogWheelBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/CogWheelBlock.java index fb5322c5f..4760ba5b8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/CogWheelBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/CogWheelBlock.java @@ -74,6 +74,16 @@ public class CogWheelBlock extends ShaftBlock { return isLarge ? LARGE_GEAR_Y : GEAR_Y; } + @Override + public float getParticleTargetRadius() { + return isLarge ? 1.125f : .65f; + } + + @Override + public float getParticleInitialRadius() { + return isLarge ? 1f : .75f; + } + // IRotate @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/ShaftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/ShaftBlock.java index 460187d1f..2b0ac3921 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/ShaftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/ShaftBlock.java @@ -37,6 +37,16 @@ public class ShaftBlock extends RotatedPillarKineticBlock { return state.get(AXIS) == Axis.X ? AXIS_X : state.get(AXIS) == Axis.Z ? AXIS_Z : AXIS_Y; } + @Override + public float getParticleTargetRadius() { + return .25f; + } + + @Override + public float getParticleInitialRadius() { + return 0f; + } + // IRotate: @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java index 5975c14e2..3f73cda33 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java @@ -37,20 +37,23 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT } @Override - public LazyOptional getCapability(Capability capabitily, Direction side) { + public LazyOptional getCapability(Capability capability, Direction side) { - if (capabitily == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (!this.cap.isPresent()) { if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) { TileEntity teBelow = world.getTileEntity(pos.down()); - if (teBelow != null) - cap = LazyOptional.of(() -> teBelow.getCapability(capabitily, Direction.UP).orElse(null)) - .cast(); + if (teBelow != null) { + T capBelow = teBelow.getCapability(capability, Direction.UP).orElse(null); + if (capBelow != null) { + cap = LazyOptional.of(() -> capBelow).cast(); + } + } } } return this.cap.cast(); } - return super.getCapability(capabitily, side); + return super.getCapability(capability, side); } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorTileEntity.java index 5dd8f032a..0181e24a4 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorTileEntity.java @@ -21,7 +21,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, private int cooldown; private LazyOptional inventory; private boolean initialize; - + public ExtractorTileEntity() { super(AllTileEntities.EXTRACTOR.type); state = State.ON_COOLDOWN; @@ -29,12 +29,12 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, inventory = LazyOptional.empty(); filter = ItemStack.EMPTY; } - + @Override public State getState() { return state; } - + @Override public void read(CompoundNBT compound) { filter = ItemStack.read(compound.getCompound("Filter")); @@ -42,19 +42,19 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, setState(State.LOCKED); super.read(compound); } - + @Override public CompoundNBT write(CompoundNBT compound) { compound.put("Filter", filter.serializeNBT()); compound.putBoolean("Locked", getState() == State.LOCKED); return super.write(compound); } - + @Override public void onLoad() { initialize = true; } - + @Override public void tick() { if (initialize && hasWorld()) { @@ -65,7 +65,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, } IExtractor.super.tick(); } - + @Override public void setState(State state) { if (state == State.ON_COOLDOWN) @@ -74,7 +74,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, cooldown = CreateConfig.parameters.extractorInventoryScanDelay.get(); this.state = state; } - + @Override public int tickCooldown() { return cooldown--; diff --git a/src/main/java/com/simibubi/create/modules/palettes/CTGlassBlock.java b/src/main/java/com/simibubi/create/modules/palettes/CTGlassBlock.java index 536ea4751..ba0f535e2 100644 --- a/src/main/java/com/simibubi/create/modules/palettes/CTGlassBlock.java +++ b/src/main/java/com/simibubi/create/modules/palettes/CTGlassBlock.java @@ -1,34 +1,20 @@ package com.simibubi.create.modules.palettes; -import java.util.function.Supplier; - -import com.simibubi.create.Create; import com.simibubi.create.foundation.block.IHaveConnectedTextures; import net.minecraft.block.Blocks; import net.minecraft.block.GlassBlock; -import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.ResourceLocation; public class CTGlassBlock extends GlassBlock implements IHaveConnectedTextures { - private Supplier textureToReplace; private boolean hasAlpha; public CTGlassBlock(boolean hasAlpha) { super(Properties.from(Blocks.GLASS)); - textureToReplace = () -> { - return new ResourceLocation(Create.ID, "block/" + getRegistryName().getPath()); - }; this.hasAlpha = hasAlpha; } - @Override - public boolean appliesTo(BakedQuad quad) { - return quad.getSprite().getName().equals(textureToReplace.get()); - } - @Override public BlockRenderLayer getRenderLayer() { return hasAlpha ? BlockRenderLayer.TRANSLUCENT : super.getRenderLayer(); diff --git a/src/main/java/com/simibubi/create/modules/palettes/VolcanicRockBlock.java b/src/main/java/com/simibubi/create/modules/palettes/VolcanicRockBlock.java new file mode 100644 index 000000000..13edbc121 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/palettes/VolcanicRockBlock.java @@ -0,0 +1,41 @@ +package com.simibubi.create.modules.palettes; + +import com.simibubi.create.foundation.block.IBlockWithColoredVertices; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.material.MaterialColor; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; + +public class VolcanicRockBlock extends Block implements IBlockWithColoredVertices { + + public VolcanicRockBlock() { + super(Properties.from(Blocks.ANDESITE)); + } + + @Override + public MaterialColor getMaterialColor(BlockState state, IBlockReader worldIn, BlockPos pos) { + return MaterialColor.GRAY_TERRACOTTA; + } + + @Override + public int getColor(float x, float y, float z) { + float x2 = (float) Math.floor(z + x - y * .5); + float y2 = (float) Math.floor(y * 1.5 + x * .5 - z); + float z2 = (float) Math.floor(y - z * .5 - x); + + int color = 0x448888; + if (x2 % 2 == 0) + color |= 0x0011ff; + if (z2 % 2 == 0) + color |= 0x888888; + color = ColorHelper.mixColors(ColorHelper.rainbowColor((int) (x + y + z) * 170), color, .6f); + if ((x2 % 4 == 0) || (y2 % 4 == 0)) + color = ColorHelper.mixColors(0xffffff, color, .2f); + return color; + } + +} diff --git a/src/main/resources/assets/create/blockstates/volcanic_rock.json b/src/main/resources/assets/create/blockstates/volcanic_rock.json new file mode 100644 index 000000000..d6580ce19 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/volcanic_rock.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "create:block/palettes/volcanic_rock" } + } +} \ 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 a683b3621..3289eca8d 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -14,6 +14,7 @@ "item.create.blueprint_and_quill": "Schematic and Quill", "item.create.blueprint": "Schematic", "item.create.belt_connector": "Mechanical Belt", + "item.create.goggles": "Engineer's Goggles", "item.create.filter": "Filter", "item.create.rose_quartz": "Rose Quartz", "item.create.refined_rose_quartz": "Refined Rose Quartz", @@ -78,8 +79,8 @@ "block.create.mechanical_piston_head": "Mechanical Piston Head", "block.create.piston_pole": "Piston Extension Pole", "block.create.mechanical_bearing": "Mechanical Bearing", - "block.create.translation_chassis": "Translation Chassis", - "block.create.rotation_chassis": "Rotation Chassis", + "block.create.translation_chassis": "Linear Chassis", + "block.create.rotation_chassis": "Radial Chassis", "block.create.contact": "Redstone Contact", "block.create.redstone_bridge": "Redstone Link", @@ -107,6 +108,8 @@ "block.create.diorite_bricks": "Diorite Bricks", "block.create.granite_bricks": "Granite Bricks", + "block.create.volcanic_rock": "Basalt", + "block.create.gabbro": "Gabbro", "block.create.gabbro_stairs": "Gabbro Stairs", "block.create.gabbro_slab": "Gabbro Slab", @@ -515,10 +518,10 @@ "item.create.belt_connector.tooltip.control2": "R-Click while Sneaking", "item.create.belt_connector.tooltip.action2": "_Resets_ the first selected position for the Belt", - "block.create.belt_support.tooltip": "BELT SUPPORT", - "block.create.belt_support.tooltip.summary": "A _purely_ _decorational_ block suitable for mounting _Mechanical_ _Belts_ to the Ground.", - "block.create.belt_support.tooltip.condition1": "When placed below a Belt", - "block.create.belt_support.tooltip.behaviour1": "Supports the top of the Belt, hiding the bottom layer.", + "item.create.goggles.tooltip": "GOGGLES", + "item.create.goggles.tooltip.summary": "A pair of glasses to augment your vision with useful _kinetic_ _information._", + "item.create.goggles.tooltip.condition1": "When worn", + "item.create.goggles.tooltip.behaviour1": "Shows _colored_ _indicators_ corresponding to the _Speed_ _Level_ of a placed kinetic component.", "block.create.motor.tooltip": "MOTOR", "block.create.motor.tooltip.summary": "A configurable source of _Rotational_ _Force_", @@ -549,6 +552,13 @@ "block.create.mechanical_press.tooltip.behaviour1": "_Starts_ to compress items dropped below it.", "block.create.mechanical_press.tooltip.condition2": "When Above a Mechanical Belt", "block.create.mechanical_press.tooltip.behaviour2": "_Automatically_ compresses bypassing items on the Belt.", + + "block.create.mechanical_mixer.tooltip": "MECHANICAL MIXER", + "block.create.mechanical_mixer.tooltip.summary": "A kinetic whisk for applying any shapeless crafting recipes to items beneath it. Requires constant _Rotational_ _Force_ and a _Basin_ placed below (with a gap inbetween).", + "block.create.mechanical_mixer.tooltip.condition1": "When above Basin", + "block.create.mechanical_mixer.tooltip.behaviour1": "Starts to mix items in the basin whenever all necessary ingredients are present.", + "block.create.mechanical_mixer.tooltip.condition2": "When used with Wrench", + "block.create.mechanical_mixer.tooltip.behaviour2": "_Configures_ the minimum amount of _different_ _ingredients_ required before the mixer should begin. Use this option to rule out unwanted recipes with similar but less ingredients.", "block.create.mechanical_piston.tooltip": "MECHANICAL PISTON", "block.create.mechanical_piston.tooltip.summary": "A more advanced version of the _Piston,_ using _Rotational_ _Force_ to precisely move attached structures. _Piston_ _Extension_ _Poles_ at the rear define the _Range_ of this Device. Without extensions, the piston will not move. Use _Translation_ _Chassis_ to move more than a single line of blocks.", diff --git a/src/main/resources/assets/create/models/block/palettes/volcanic_rock.json b/src/main/resources/assets/create/models/block/palettes/volcanic_rock.json new file mode 100644 index 000000000..42d465d29 --- /dev/null +++ b/src/main/resources/assets/create/models/block/palettes/volcanic_rock.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "create:block/volcanic_rock" + } +} diff --git a/src/main/resources/assets/create/models/item/goggles.json b/src/main/resources/assets/create/models/item/goggles.json new file mode 100644 index 000000000..88f284791 --- /dev/null +++ b/src/main/resources/assets/create/models/item/goggles.json @@ -0,0 +1,164 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/brass_casing", + "1": "block/black_stained_glass", + "2": "create:item/goggles", + "particle": "create:block/brass_casing" + }, + "elements": [ + { + "name": "frame", + "from": [11, 7, 3], + "to": [12, 8, 4], + "faces": { + "north": {"uv": [11, 0, 12, 1], "texture": "#0"}, + "east": {"uv": [10, 0, 11, 1], "texture": "#0"}, + "south": {"uv": [11, 8, 12, 9], "texture": "#0"}, + "west": {"uv": [4, 0, 5, 1], "texture": "#0"}, + "up": {"uv": [9, 1, 10, 2], "texture": "#0"}, + "down": {"uv": [10, 0, 11, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [4, 7, 3], + "to": [5, 8, 4], + "faces": { + "north": {"uv": [11, 0, 12, 1], "texture": "#0"}, + "east": {"uv": [10, 0, 11, 1], "texture": "#0"}, + "south": {"uv": [11, 8, 12, 9], "texture": "#0"}, + "west": {"uv": [4, 0, 5, 1], "texture": "#0"}, + "up": {"uv": [9, 1, 10, 2], "texture": "#0"}, + "down": {"uv": [10, 0, 11, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [9, 8, 3], + "to": [11, 9, 4], + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "east": {"uv": [6, 0, 7, 1], "texture": "#0"}, + "south": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "up": {"uv": [7, 1, 9, 2], "texture": "#0"}, + "down": {"uv": [7, 0, 9, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [7, 7, 3], + "to": [9, 8, 4], + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "east": {"uv": [6, 0, 7, 1], "texture": "#0"}, + "south": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "up": {"uv": [6, 1, 8, 2], "texture": "#0"}, + "down": {"uv": [7, 0, 9, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [5, 8, 3], + "to": [7, 9, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 8, 8]}, + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "east": {"uv": [6, 0, 7, 1], "texture": "#0"}, + "south": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "up": {"uv": [12, 1, 14, 2], "texture": "#0"}, + "down": {"uv": [7, 0, 9, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [9, 6, 3], + "to": [11, 7, 4], + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "east": {"uv": [6, 0, 7, 1], "texture": "#0"}, + "south": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "up": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "down": {"uv": [7, 0, 9, 1], "texture": "#0"} + } + }, + { + "name": "frame", + "from": [5, 6, 3], + "to": [7, 7, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 8, 8]}, + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "east": {"uv": [6, 0, 7, 1], "texture": "#0"}, + "south": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "west": {"uv": [7, 0, 8, 1], "texture": "#0"}, + "up": {"uv": [7, 0, 9, 1], "texture": "#0"}, + "down": {"uv": [7, 0, 9, 1], "texture": "#0"} + } + }, + { + "name": "glass", + "from": [5, 7, 3.5], + "to": [11, 8, 3.5], + "faces": { + "north": {"uv": [1, 0, 7, 1], "texture": "#1"}, + "east": {"uv": [11, 0, 11.2, 1], "texture": "#1"}, + "south": {"uv": [11, 0, 17, 1], "texture": "#1"}, + "west": {"uv": [11, 0, 11.2, 1], "texture": "#1"}, + "up": {"uv": [11, 0, 17, 0.2], "texture": "#1"}, + "down": {"uv": [11, 0, 17, 0.2], "texture": "#1"} + } + }, + { + "name": "strap", + "from": [3.9, 0, 4], + "to": [12.1, 8, 12.1], + "faces": { + "east": {"uv": [8, 0, 16, 8], "texture": "#2"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#2"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#2"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 1.5], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 1.5], + "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, 1.25, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [21, -180, 0], + "translation": [0, 3, 0], + "scale": [1.5, 1.5, 1.5] + }, + "head": { + "translation": [0, 5.75, 0], + "scale": [1.6, 1.6, 1.6] + }, + "fixed": { + "translation": [0, 1.5, 4] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/volcanic_rock.json b/src/main/resources/assets/create/models/item/volcanic_rock.json new file mode 100644 index 000000000..b3e8cc133 --- /dev/null +++ b/src/main/resources/assets/create/models/item/volcanic_rock.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/palettes/volcanic_rock" +} \ No newline at end of file diff --git a/src/main/resources/assets/create/particles/rotation_indicator.json b/src/main/resources/assets/create/particles/rotation_indicator.json new file mode 100644 index 000000000..4fdc55ffc --- /dev/null +++ b/src/main/resources/assets/create/particles/rotation_indicator.json @@ -0,0 +1,12 @@ +{ + "textures": [ + "minecraft:glitter_7", + "minecraft:glitter_6", + "minecraft:glitter_5", + "minecraft:glitter_4", + "minecraft:glitter_3", + "minecraft:glitter_2", + "minecraft:glitter_1", + "minecraft:glitter_0" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/connected/translation_chassis_top.png b/src/main/resources/assets/create/textures/block/connected/translation_chassis_top.png new file mode 100644 index 0000000000000000000000000000000000000000..27375ce469f63063118a8d378fa2e4954d858df6 GIT binary patch literal 4895 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/connected/translation_chassis_top_sticky.png b/src/main/resources/assets/create/textures/block/connected/translation_chassis_top_sticky.png new file mode 100644 index 0000000000000000000000000000000000000000..4055870c443c5e4963afe2e11f07507b8cb03444 GIT binary patch literal 5141 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 bVF&!#K@&zA-+s=$?gPwCER2hcoWlMGc={sx literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/volcanic_rock.png b/src/main/resources/assets/create/textures/block/volcanic_rock.png new file mode 100644 index 0000000000000000000000000000000000000000..970d8e7ea9ba68e7eba4d3197d0ec602c4d48082 GIT binary patch literal 682 zcmV;b0#*HqP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TVM_IPRIsIOJs)m24*o%%*`zv27r_ieM+ z(n1ze%p1MT)8Vd7OZ+>oz=+`LvN+gj_0YG4WWng<5h-p3hrv|lIEU-vV!_jX_rCho zhr?juu2Ynhie>_Q$~hIvcquf5_&P81nnFY_`Cv6GSSW#mkqOaS7E{?9yKJ#?T!;Zv zDWoDMmw*tZ;Qr9L$-(zSyKCE*$(;^OtKs#wcBa9cBcf5FH=+J7lRdq79-{Fx8?aZS;@WM4sCND{pbR4TGwd?z11(HgNDPg6;`m-1g~G;Cb9 z*?AyHff}nIm)jZvm=PSFzV12j%jgV;vvZdvC}1`47_-a8YIC|f7K)eKlr~h7!q=ha zs-~01bvqhWfrJ#6$QF~|GUHf@o&EUdd|i1>;5;s+V674oa^E)hd*giibDk4nk3*vY zra7FB4+Lt*@a3|=)0Z9QI)w?oY}-%`5}6dPfTn^+t83H7>osKDe0Dki2j`JqcuIU> Qn*aa+07*qoM6N<$f?9Vv9smFU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/gui/filter.pdn b/src/main/resources/assets/create/textures/gui/filter.pdn index 02d317356fa064554a6991611666b73ef382186b..31cc0e7587e890715f360c8c8eb61163a46ee6d3 100644 GIT binary patch literal 9152 zcmeHLdz2LAm1mZB#Dyd#8bu*w6|=2WzaPpl`Kqhm@Am_Btgf!AepFX?S5`68lL1u+0$v!+{-TU3!{RJ_$uwsQ7v?#&UvQZJ{D+K4TWF6sqdN>>SB!(g2}?q^L~;U7=x;a5bM*)dMA6 z7gH`0F(D#qBMuhBv(7kHsjF&C3Mc%mJ*=w|gdVvvkJp-9DpnJZ* zGBRYezyQ0|kH?Cdau*dZxzn+jrV^DBH53G`;he>Wg|I})olW?XOt_F>+;Fa1Q+1JS z)PRt#5NbA9?O9Ebs_V356@)CPA5Uo@?_}Hor|LD8NHkGoOk6l2(!i->Ty`Xhv+DTqX|@R^#vK00G~Xk;1FUipz;;4`X|i6jpbYr zFO&plS|W75ARs{jYm`CU4s{ZBl~6Rn__K+ah6!UN1677Lks)(SrV;lfoT5EeHX3sd z!Gqz&%E$ENij`2ymXt%ZR$WnTxuU2qcyPQ(2V43kGMW&;^bKEt0CwOvDy-&{amJsH zg)WKr;}NG@ts?!X4Fv1%5UNM35umF2BHD_AcSW|%QVrlFEn;FZl~u>GDhp{KD``gK zfm}11bTkpSK@m3SILI|>Ndmk}!SsZ@H7+A)&60+oEmcTamB7^%l#ArGEv|EQ9GXZ) z^=8s%LS5EiFd%w>zr_pmwbyU7P3m2+8)7LX_du+5u^GVbP+;P@p1OonJ6B{-gzk>CXj3yXdH<{Jbe?aJnLZi;5xO z2xR;`moS+45MVQn5U~0(*)p9lAi+?mkZJ%QN}$zJA>+}gGI|$HCE*-EumWd>2{TjY zj2czgV-vB8!398o(@Ho|(nV_7NQshgOPoP4jzDyA+>i;;1>P;1ZKBf=i>7O}D8ke& zBw4~TUIn{GA(Y)2a??SD6PJxVu|1$8)IQin1rl}?{52?n1N z)POpQ3Ji|;47k&fAtL}p`G7i=NognN5Kcf_3m(L5^7%A%kEjxWwZIB6r*Za}l@8!K zCPc)6tz-yi{2@-P^HnhnwAH!>nA^R-j3gNZPxKXevNPfj4iigNP#>!cuUJ=!1KR)DdXRs;|KXRuSlfAnAxy za(udBR_bfgZ$=y}r?nuefGOwJ>d7RD`z<6a{wgYo!{Qv%ag+t)F>l7BPZQa4!xlg? zNHt4`(`lX8UGT#g)=88_Dq6i>harvQQY>N*Fg%|2$GfVW-(C_Z2FVrz$)K|qlq!Nb zjk}$8Z;bcD5>PIf5JZaVDnd4FqjVN?mQdljf}}R6wTRCG@_9`y;V4Ba8mKnFsR(Y; zAdPeus>Vi5Vnf}qdTSBAHeM6YJq;nDvFqavaoxVDZ>Y|BIQ$c55)K++1MjN&yjZ!piVgk5i(Mxm@1d*%?wbDr{ zOBymRTBGJ|#!Mto^Xalk!mW1$3~4xGR)fl`HWacRtsxo5Rc5;sr7^ueWTeGH#bQk7 zO~Hl~ggKXr6K0^XX3}A)lB#HRwrrd;iAjF|1PeK=idh4!u2S;yh}UPf(Wr_9@o=ir zFlRYRM+YJVK%BrCb2zefHtN%bRf)6+Z8e*Lrz%Amy(vM}t%OZPRW%SO^ELw&sAX!H znU`SpaHd5N*VGtqSj!`%&)@}aiP33P1;6A;d|X#|2vb>nTFM%-7lN0u7)93_S>ntz z8t4*H4Vq&!2DRi@Q_fNr)+$pFSgX9+Kn66dUaxVBA>J3uhFo!tN^o^$brwBK7tw$u zVpT61NJ&UM*Q12`yDa3I$s!jHWV{m_&P%kqQ&lP#JrG zRmF@Pr4c!-nB&0}nKi0jhy{o`#~Mtqex#gJc_|beY#>b)q#Cf+>gq}&SVQVSrA9<; zyr9NnZlUN@F*KV=g*94M$f<(?JgGP7fIXJ*5OrrVsLNT%w1K1SK0WXlkqA>Z#V8EI zsz^=OR4z0n64!~;6fR66>!uKA8vYJ56I1y}u|*!JgA%Og=};=IRb{%4sR8mYSgo&aQn6v{AXq=M7qAoz0XaF~FAX(s8lZd!|N=(7n zv}Y+UqRy6sEbD{$#G(UeGGUC>ow}eVM@CWr2?Af)=Q2_xG$}*{10g4!Mr_%TzZk+r zBw-Az3S88$qcnNa8Ul#Lphsc7%YmTea>9L948yv}(HPu#E*Ok9;7Y^aMsyD5Ml;|+ z5EkSd{LP|DqcB~1U9bYC(x7iYa2+?^F%@=Jk;3McfjpkafJWbOmQ?%J!J|2{FsGWA&TrM7@DvCg-%T)%c z|CjxLjPn4dH91vcElYcVF%u`1|MUQLhhqjCS9C*mV7m^N+t^tLZdh4w0kCEh$QD5lJr^S6-(52r4>WWn*a zOKoeJVMs!NM=1O<2g#CLo>&Hzj^j*?gmB#b+LbFWO^pa#o~7?tT;ho`$K*3p=}<3& zpTEpP#$>_`gu$q>==7x8Y`OQ2|4HzBSKg}_KW*-G<*twqzjGm1)8@{Ex0y=!Cv&FE znN`6#=$Zw9nxxwGL-c~PD- z6rmq;Q%jFdA6_VPvpRiwR(YVcJd>T<87Av_<>U)4g6^F&N16H>{NA~6+B9`Hgj7sy zfh!}^|M;nJ_>2p16Ms5PRf1@Gk!;MYD_ga#ZPr}aaqZucU3qGmfYa)g>U(E>26kb~ zm9EA4Z2JAtS(vH0%%`CIP8@S8>(eWakUEz)qHuq27t-5 z*>)E4s&G4N-c?dGij-?%7ji|4)&jv>QXuxE5Z#}I01>qEaNC*7fb*{c)GB}rV3%nM zpcw+S0L_;Hp&ggBE*s#1YXJVKgQ_YCzHRg}@aL`q)+xZB|2QyI?5_o0(AuLAVD5Da z@br0KfRC$6gtg3(Q*+|g=h1&TIkrlK0)G9}JdWmt5?*O#^H!CBf2b-XC*(21X%)K7oCi9e%oNs{dGnM}To=&YCnt`s&1}Zado2o$!)=G48 zfLHm;TnT3`H5CEzsyaN2hh;EJ&g2Q4Rl~suA#<`M zMRFXOg~M~(+FCKC1e0>L%~nikg_!dElvMg_U|1{WD%b1>7Ckbj^)_SL$dQinLfZ|$ z!d2_v?wqmzsouy?VU=!v}svZIFH`zxVFTw+uO!zHr}5U)h9=FSP#n&@BTSR*r1{a5Pq0_rkq< z`Hs#p%R}L7j~??KeE&%Q^{XFyD!O{r!j}eYJ;d$*_V`@~JLVO=HxKu`G5*oUFKxy| z-4|YaaryG)-}uAG=qPfs!zX|6;lgh}-QA2J&8@?I?JorHYR*60@u*KQMPA?7|LUur z+c%v%a8CZ?E8l%($BrG&Q|}+!`_{&uo~36`?BDXoef##YBk#O(ze^q;xS+pjpl`x( zU-{UuKM?3W(NU5|2m3moC>*og9XQ(c*goE{=j{(~8xI_o*UVq^ef_rgfAsR%MFVnh zxbJ1drhk|?aBh%n4s@l~I!0cJSS*$gAD#H%TyJ&l5c|MQ&8;JStDCUlFl>{nO7GTZ zz?lB&xA8$Gp`$ZXU&$U zkEhq3CJSSMlViQzrxd1pe|*Bw8(_|Unt9r0&}Cr;gW|KXwaZxjXj(14u$N#F6o`uuO5{^`G7{5qUK z4eUOC{)3K@;U3@SU5}pL^VI6*z~AreKQZw<^w%2`7duCWhWl2(=aI+WZFZbFH<;_} zx%SKB+|x=s5d&-^7pCPaJssHR_rhHk@Fe*=$+AX3d)5FPqKgt<9|` zyI1sBx3>tCh2{%GUvzJk@r!G=KYaS3YGK=xvwM;2&-d*9sOQ7|ubkN_eenK)Gsm8N zV%@rv!<+jx-z&h~yXYaqGmo8}|59OB;jZ*R{rR_#EVy~-fjuYqc~2L{b2pCvVZ-Q( z0}nixKk?3m7y8FeYR-S4?EY9!k7clabAR)J{X;iA^GyF;D;^q}ZhW=5tI&7T(lu`# zz59_qdG+&Sd!N1L_I>C39^CcDJz3aZb z=xk4~yy5Njo?XjcdquZ&XlGgO>FXZuvm8F2l(#?U(IoVN_ z4|emvcFYnuC`Rs7_#S^!DXHPd= z4X3{;ue$j=y_3pd+vNLZ|8Qh*VsPWV{N{tJd#AsCe(>EDNA8=yT7F!&&2sB=%J^{K zs}p^_$Dh#C_wbtslu75xa(Uk`;PAy~*LB|fK*J_C$6t_5^uWgO!PO)42m8*p00&kL zKX_<5EuUmB(8B#=YYmcb;qUC0~{{aY@>na^R8k zvS#b6i-zT&KQ}5rr62Da}`b99#5KU0vN>y;ODe=12`c zkW3~+1OZ~O8QHuy;t|$ckg$}S@ z7&5RrmB1U<5H5wqmg5_=coG4J+3t*}ojAC%a<^(kiFm=UA{b0ZNUjC(nC&)xGeXhg zptL^5masYn3ItK+qq!{XwK};``k*@E3+50+MVr8_OoaqP*|ZispipY9Pny5xBj6@U?+N;s$@-U*edn1gKr$~E)X+55E+HEP5UFpP~ zT2DRzquHcgNn>fI5XHz$I>Ced5|JB|@=_8ADe{6;lnVKZDzj7OF>BHhxs0caAVDSW zQy3Ag)@siwA~7|Mc(1$9GEzpCkue${=FgFWVq7mV+6qR8Rv&i7BM^_53G4M487vKj z?dG6cqCp|lY>mX^QIAWl<3Us~?63u5dMU&>M5qU2(&4yBo{*_cByEQ&wK9u%boP9+ zg%86?qsfL9VU%>E2}ua@@$xD?rOi@Sx*$r0H9SZk%qk(C(TEBqJWp5~W~_EBPX(N6 zOdOEG7NIF@O2*|fm)2@-M)C!_Lzr=f6ntEz)$380u-U7K5`nB(oQlzrl#Eo$!&%&6 zz@Pvvw8qR{wIz>)ieXXC9OqjRX%f-l01SxEgR9`?pwXocs)Tw(?yxA5a8%0Jm0pU* z!%_*&4~a_fv59F~y=G!#~vvl3@9nbo8nBxDl^AeEhQTF|tlAPrxe&wG@RE<_5kA`}XU zJyALmvieU zvpEuuqB=O0A@np8l39WUosMVA2ZES`GTOokN=(-6=R;rtlm<)_!FYLTGUe9mVnP+> zOkiOzl_CS8qCx15#{#4<8}%5K9tk0`C_I7`O8YRA7Ql-H@e*{3a80zCavLK;9chAm z=@c&{$s41E03p(1qGFooGDawGf#;+!Q`(Opp|k@-^jO}UL$cKo~C=Ku-H5cI&MrVpyi%{$j zlUch$I*%*Lpu!Y(*psp40gl6VR05feUV_ovbx1ZrGMRuk?)LJ+NpYB$;MpNlI+GM- zXfvqgXP$pP_JfJI( zN5eiPW=V^ckrZN+sTFR6#tS>Wc^@x`rA25$3nvn&NmjH3yo8@hU_}y*2t9FQpxNz~ z2u%?QlPzZTz~OG8$^j6Is5xa!Dya#_q=|4i?7{4WJRWsnc6U&eu$Uzd6m#b^8ViU~ zU$a=lv%6`V3y&sHg(sED5+0$-C1$SR4H5{2JP7s0C~1^PNPu${SRxVh77HP7(nZn& z8Q&kLjC4Yj&qPsyKpB97gwU_lr&Ttv9%)kHw&>I*3}bv=ry~#Nj7FcBGLx_-t~2F5 zgdr>TI(nZ^iLJm$k~ezZ_z!qE_x z#0q?8S_7FKu)yDJAR)q|l7;P=qSufNiMSj=C&Ot~o=8R!f6nA#@SIr}3%d$7hsGCG z$x+BhC~;F(Lc|aWfd~|k&SthMtU?^gCy{8fS<7!$ix3@8Y}GmWI3n`pa(0WJfuaOy zFC=k@5hWlooR{-LkkKrVz=$MJl=8f^LnzHiAOVQPyvK%UkdVrcM76jwoy=+YHpGmC z9Cjp1Hmi6hVKyv^HTzR29?GZ@OO*0!bBNii%7L{@3J4s5_;J4}5VVT9ILur9Rzh0z zlO{N?sN*H3$Qullh7Q`qQbZ9lSp$e69Ys7=r&f%}14=sQD!PSg%z`5xhgzGP*CDRR zAVy;<9kk{0s=Azx(Y8DPRKATGe4s7FWYzNCIa26>lqXAx~ONlGGlxgqQm zns^@Az!agNLm(zSU~n!i2!?fjufCwQX=tm?n}d9i6&0g?JB7ix0HGYPM<|OpvwBSI zp$bk-0G3%J7Awf$bzWAa4q@haF=AIsRCKyuFa|PiLBc1@@B)F{$a#~QxT;o9WTN*!b^!GG!pc>#kR1A zFc z1M7_vIvvQ#6rr-JTwKf%z*lHE4>(#C<#K-93?tE)BBRda7;Q|Uvx#U`P8Z>F<6n#o z2P0!-5h;>{6Ea3=@KGi&CZQRRQLHN@q5@ec)~ph06f~GfB_F{d08`Cy?S18SXA*b&w`iZ)p? z3&ApPgr6roBH9UR<_~LPKP*>f4JjGSKqklw>S)5Fk$7EB#t&++tVIbkMq@K2%Datx zKLlzz@MJzJiK(+p0io0cFBO7#fSZK+oQv;)Ab~g|qLhi|6eOva%qVHK^JL9RK$b2N zaI!C9E`}xguvGqGT^K8Ir5E8fuH_ITN#I8*`yvBgdidua@K0hQzuHZgt%EZ!U zu?p4;MH->nZ^Cnayx_J|LPSxBxtsyGm;i5?+;e(YokIbQ2kShq^gE1!tMSAq-8t8v zaJd^V2)#)WqOs`^xgti#T?}H>CDSy=y&$&qDN}~I8sm0fK;aAk9-s|Hg~uH5)^i27 zCMhUja7!3XNFgCF>!I=v2+b!77E=hkVC&;_+{WdJv_yzx#3~0v3gV%>PQ`JFDw_!S zVG$jSg2~-}5OXe#Rzz#jR8eLEBIFSPFDxUltlAD3h-Y?FQ6a9xopswGIw}AmkRGyY z(0rVP5r0+)N*RA#Oo1XDGsG#74nfJ8A>DaFS_mVdxR4i>MVKsN118n_0y;M(0z91M z(udTQM93hpM=Fb$Y_fa?!x0uxme(JLXtS=hX8_Vv3h@z)7?V>E*7h74u}!j3xa?rj2H`u z0KBG2rF5OzAzm2Kpz^3GlSm7r7=i|Ua1?AeAX1fBCqebDOo)fb@nR;Ti^7Nx$BF>O z5}n?s%wqL=!>M!>Tz&}>v=ixkKv&QIe~KBvpZ**bR0IW~h&I}6n#cSVj<@Q;Jk<5| zMLiCpL4MlEgu?_OLCB$EIyJRZ-QOGfJPXQk%z+q|xfRi`dSX^#+s zGdv9?gbD>3P7Ay~xzsJ?1M^D6dDXlv^T3w6Fqz=10$Q!kpDR*Wv(yfSb#cOE{=inv zK}aJoCHX>$B;ilU`6>%pw*iP%T!p$xcUZ^I3iA>t{(=3Vj4I?&7a|U0HXiZ^gjSg6 zonI61rAgxTNyMT5f964j3R)3XK~is>qcEi@gav%G#|8ydaVY{3A`0S#^bu9F&ye*Z zXd%MLNUt>&7Z!LKlgt~&Xqy{K=15rYvt+;m#a@X(5+aHrT~VMVX$8PMX$a&L2}*^c z(R4x%Ypi((rZDN_*}Nj5(ps`8?KUPMEGg#Wfe_d$0`YUjPEIHrNxLne*q4BK7e@pU zDQyzToo-<`1tkarc#$WY^_GkvkyE)%v@jJ+i@Yg;#4QyUGd4&_#6lnNfKQq$7RAyy zk7r5cad{ZBm{C8X@Q4AGXt6AK+MGstIa^e~)p))DZ1v^xQK~4@5K>f>Mw59AiUk2T z%EXGaT4c}RGB@e+hg`*rKqnCssVEWV=SVlC)&@;p zDa^}znJ7=FBNDt24DuA1BVp88P!&VUV<;*_)YUl5DR@#+OsC>nQj|5xoM8s{@pA}>{l8`&K!CXbt`!w)mL}IKe`cq*J>pb&oC6$n826} z<&WRB8f5};B51%0j${l=G$xpMd=V%9)7ME&1{o4dWEO*tj}x?tpi@a23oV}Cg?jD!L>kXmp{&6KpgdT;l_;Isk2b--W|(cpn7u-^Wrp5G{;hg+*B|R2v!=F9Qvq_%fC! z!fP{rT(ptDY4OKFlWINJw3-NkZ+d*mn$>YYMr#D%vtOo=!oWwrHLL3a8rKB1np7ZR zWdfv&->kASCPFMgkj6S~Hp~FKa<*N3({;1RxLG~{nxGG75z2w^`Yb^9{3PIG;+08| z95OHPy{iImxlSO=3A`0F$*vIy13`6x@Ku3e9ajV;9I#^Ek!u4$jx*3T2YQt|iCoKbrp6ELqPL+$^_W zOXvzBL;6#7TCb;z6qQV2REEIlB{V~Y{Xy*3dMEG0JaXfFLp_b$G=DvxOsatOTb+9&MuYH;>wSi1C!*LKZMUO!(ipw5MNfG3uH4xBz@>Cbc5 zoRRC+{sOpI28azDS803&cg;DVK42xdShfnBJ{+(bTrc7z|Ib#%$zKuxs0dk7H~izZ zYjA?JtC;VgdFCWV`r}t_xkc0$@24kF2x&N!{=b*T34Y*&#S?a&GH3yj+5`Gf<)9PUfmq@^hZz5=gKN!QQ zB$Eg&Nv8ZkB2!paH-#w~!Wy_lb;I9F;n2|VvCm)Y{5o{&?&fT9)!~c31Z=XT-nUw~ z?91S$VF9~n5Kz#6@^Bqtb^2;)S+JB7#T^YC#_NIbkK7#x_IgBI!F%1`U*UQ<;B!7- z{8e!J_=g^wpT2=@I0dHXQ~=!z8o0oyOXYEQT!j3I)VsKz)!_`xvX4gRW!mVyyn z)A&GR^kc{!-+1Gt&0pEYcdqW1-FnxzmgvrZ=C1MQyT7;f7mxA3`JL|`+}SmD`8mtG z-{9}*xbHpT9f~{<#~tgP$Ho4ie*RoTHQ;{W_@!s_FP>SI{QU9K?+f>odsc28+>~s8 z=w$ehD;^JSo>-yWeR?IdeeB{LExG-TH+T2i`(Nn}e)Z&u#xr#LuE)1-=|z9Gukq9$ z@8w2D-|?{g=eMmp)ntsVT`@A(`EIwpb=OdN#lJ|l*1p+$e%0oIFEwWGHXbccJYlSf zULK>`ISBo2kDHE*O`geif9G)Z1rMoMfA?d3rO{3A9(s0^n!H2rwD-<-%`dOtIr8Hzhwd-@ZFT<}NTc7o@${Ep?VAS3{q7)3^Ti&X1k9EvgD8o`!br{X_pR z{A>T^j{8M;-{sc+p~4Nf!}AP&iTY6 zuk^OBQqHVgpHDr(lC$N`&TmG~x3G_GtsNLESI;QMr^^X8B|bWQ?+?z+U3&SJrh8_7 zRVGG z>BEE7vrklV&zzCHdH(pWZ}kTIzc%yc?|y)`uWUScgq2p=_s_Q9zWdYzeM@%JFFms7 zfz!sut?O>N>nJHW8QpXKg#7Ez4e#q2JTO?JHdVgRa_sUka}#@c>Y@EjE$rY$_Tu>9 zLwAZcRC*q{NWaiMGV|J@MIROP*+h=;-ybq;%{(WYBcEcTGt?#7E{f|uj z=0wfjJ;olI-OK*y(6a-jo~Ng3L#xK(&&};i?Ap*I9qm2WRvsK0TDhg|xwDT||6m216w#_7s?_Swg&dw+T6HRkdU=f1srV1_<-dE3B@=}YvUsTm79TYj_FcHuF8 zX2ti4ZHK3Rdu-swbN4PWoF)UF|R*TM3$oqO5V*~y+-N72-j+jOL~qI90Ao@%u; zp7|yFNN3Yq2fv<}oNd}Wak*pNn4zm>_F(Pw-YK%WZu9TPYO$4jPqsck+5jw7D%G|| z_AETz_iuZq4)omo)k16HonC0i*v6iRN5oH*UYsbG$fiv9Nb8E!xcu=go08*Wl}E<@ z*S?OC(G6{V407O=7Y?^pCy$pZvt?rS%)yp-?&VLv@QoqnrPGy$&Nf5e?VTG&r^}fM z?erdY>YYl{skXrrCkCpI_LvV$&$gYf&OXxFlbM*D*JpBoeXalfuIeqDDtq6hyN8yq z+CFFBJGQH5qUU1uP;I6~$p$NPyU*E2zuh_d&D!#g;^UsPqja#cFjjteWZYbtZGW4c z85_8L_t@OfkY)I`H)lJJSGILq8du#_E!=mae|)=(AbYwugAe15cVS?5ohPHib2 z-goYS$9ZJi?_O#-A%VTeMx7Qy0 ze>-^jLyZf^gzST#`as29Z3hk^Yk^-U--zyf!L~t|MB4V*wOo- zRZVR-o!s)r|M<;!Y6s4<=guwu*)ydoy?J(I4|{RTjr)&ZG2&mJ1NRpz6T{t>iBhrB zUaF1$p}nQF`S)w`kA3Kc$>Z!~&*gKsK3VzFYu`CceVRev~Zz(SpIgYqc+&{-rj+dDAvo!!-3{}&$~yZiBD?B1UDkH0Pdk5`gC$JtkFU8SZVT{wKH z{8qIzUCSOi#A=SW@p3mGVK3JVqkr61-P+bYQ9D|lS+SS7`R$7%jkl-{xSopjuxQ>JzHqv!%ubA05;yOCy>x!Su;a$*(&e-J`x|CE zMoQpf$jeQVzvk~yea9Iie!H+J{tr&_DfWI1zl z7n@stl11lcTh5ezw*N$Me5(9t>v+BcaPC`wR#t86Ov}0l1}>DR$Cyh0(CfcR|L9lT zSRnt!k!MQJ_O(_!EOV2k-qQo@do}y>C*OOmw4MI(dvi_PdSBeTyK;8RD($2;FxxRZ zSDtQqo_+gLqV|I)=ivaH{sg$P?03BqWXV4NPuY&P**jmEWVf9v4Z5cv%dwWN03c1p zp6%?@?^oHuNZwQafGx z#KSQA5eoVJ%;XGve#3q5|M6(m($qOuVSCE&PgVMNt}9=DxeoT>uGl{%tnBx8)dOsx zY4jP8kV><|lTWOhm9c<`0LUwcw%?s-V=K19lefOux9`-Q!>eK|#{fXPMyB@l?r&qu z%)|T5=WCuRD?ocoaq}Ls#fNt=7ayCOU=NqZPV9g9Qt7_fFgx%o==m4=*G;hP{g)5) z4Kc5>XK6OMqjT)nY}1CRk#+Qd0CZK$%(*>hYwY{4md0M))O#7EboSIwy3B7@OTS~; z>U-r<*ZOxxfPmRCRUbRjR^5J-eyOFWw1@pkwTnH__u9HoR@m=8TXjt=-&q1u2cN%9 zzz+64LfhxihaDRCS#v}VSL@uskX?(mTGcG4dnkT*4PhVwVgfndfN`)XishH6%9_T ztITk!%`wp(0KvOTzy`kq3#km2*t<{l)PPyzUFP3j?wCg(*ZsMTU-?6=)HlfGBwu+&J;l?My#$c2-~8uzdTZZaULksZB|u3ptrHNuXSx;Ux-!gU$CPL+DtizH|G zUz(?@?CXQW2iap&RM)CUYx@8Mb`!M`=aFNdd~1SzLb`_qytd`=qWwq8m#(GtQWyP= z+U`wz*tZ{EQ(Yy#?{4sl&sEkRRM!iizNWe!5cRu*$$**qvNnY6Z+UBy(^5D;x{%Z$&2SKmfA?02W|0l=S zPrQ+W2PZ3_#vIwv#$L)@9Pbrz^8^x4nL%!nOsUX>93v_7k%$d)Y_MT|P22P}%}8 z_CWVe_Tt;69W`Z3C*bs^RuEh-Z$1M0%A47L0PJ7l!tF|nnSEmK5PhcFv7x$E#vT|P z4|EN$ovr@wtK;|4@N}1|l43`<9bv;SoHuT0tIf{6=VL27*gI$2Tg$(={oKWoCgpRl zZ0tYJPQ6_DIsVew<1f^b7s~9Vd$+%G=P27a$#zx_%)D2-d(+%+PJ9l;N%`BY}UXs+OcrvxvfR^jk7map)sI<@$efztoHVd z9P#dCX9w;atW?3nSj)zd%JMs+E$l0E?K@tcU{7_^p} zYPQ_X9vK*#d;j#<(A@XeSNp3~2(0Ubg&mt|IR?mg*HfjbrVERz2k__EJ;Qej@Nd_K z**mw_4zs_weR^bNneFIdCpza2bg}k>8%Ime4K+S`f<>4oZFOYyrXx*~AHOrgvVVQ?@;^cOUpw}mOSOex NUH&fk_Ho04{{wx=7NP(E diff --git a/src/main/resources/assets/create/textures/item/goggles.png b/src/main/resources/assets/create/textures/item/goggles.png new file mode 100644 index 0000000000000000000000000000000000000000..bf6467f88cdeff586de4cb5b3c6c48676c39e188 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!GE4Ejv*HQ$$$R;w`aCI;2HU0zk#?kv+xvu zp@QpE|E*uDacsk{Pu^~mVjiqh{`&v+_xC)LY-D&=>)EBVbPAdr2zCAOzh2Fa%}gwe zjZrSGEp_?42Gc_fizjQz-{`2_Znwz8Vg=W~=Z_vGJz%aXI{I_DM$rj|H%$(@7yr+R z(czh2XJBZs`Csw_maIn)o+U*TywLOOHE<}?IlvIPv4P1!??AhA$&r87TAUBc)XaQO zNU&_0d-dOL#>E0>9GO`TH%t^1>RVVP^nZT+&w~e!o;