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
This commit is contained in:
simibubi 2019-12-05 23:42:01 +01:00
parent 3a7d3f8562
commit 9f6022f0fe
62 changed files with 1168 additions and 204 deletions

View file

@ -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.MechanicalPressBlock;
import com.simibubi.create.modules.contraptions.receivers.SawBlock; import com.simibubi.create.modules.contraptions.receivers.SawBlock;
import com.simibubi.create.modules.contraptions.receivers.TurntableBlock; 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.LinearChassisBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.RadialChassisBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonHeadBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingBlock;
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.mounted.CartAssemblerBlock; 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.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.receivers.crafter.MechanicalCrafterBlock;
import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
import com.simibubi.create.modules.contraptions.relays.ClutchBlock; 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.logistics.transport.villager.PackageFunnelBlock;
import com.simibubi.create.modules.palettes.CTGlassBlock; import com.simibubi.create.modules.palettes.CTGlassBlock;
import com.simibubi.create.modules.palettes.GlassPaneBlock; 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.CreativeCrateBlock;
import com.simibubi.create.modules.schematics.block.SchematicTableBlock; import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
import com.simibubi.create.modules.schematics.block.SchematicannonBlock; import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
@ -86,6 +87,7 @@ import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
public enum AllBlocks { public enum AllBlocks {
@ -130,16 +132,16 @@ public enum AllBlocks {
MECHANICAL_CRAFTER_ARROW(new RenderUtilityDirectionalBlock()), MECHANICAL_CRAFTER_ARROW(new RenderUtilityDirectionalBlock()),
MECHANICAL_CRAFTER_BELT_FRAME(new RenderUtilityDirectionalBlock()), MECHANICAL_CRAFTER_BELT_FRAME(new RenderUtilityDirectionalBlock()),
MECHANICAL_CRAFTER_BELT(new RenderUtilityDirectionalBlock()), MECHANICAL_CRAFTER_BELT(new RenderUtilityDirectionalBlock()),
MECHANICAL_PISTON(new MechanicalPistonBlock(false)), MECHANICAL_PISTON(new MechanicalPistonBlock(false)),
STICKY_MECHANICAL_PISTON(new MechanicalPistonBlock(true)), STICKY_MECHANICAL_PISTON(new MechanicalPistonBlock(true)),
MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()), MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()),
PISTON_POLE(new PistonPoleBlock()), PISTON_POLE(new PistonPoleBlock()),
MECHANICAL_BEARING(new MechanicalBearingBlock()), MECHANICAL_BEARING(new MechanicalBearingBlock()),
MECHANICAL_BEARING_TOP(new ShaftHalfBlock()), MECHANICAL_BEARING_TOP(new ShaftHalfBlock()),
TRANSLATION_CHASSIS(new TranslationChassisBlock()), TRANSLATION_CHASSIS(new LinearChassisBlock()),
TRANSLATION_CHASSIS_SECONDARY(new TranslationChassisBlock()), TRANSLATION_CHASSIS_SECONDARY(new LinearChassisBlock()),
ROTATION_CHASSIS(new RotationChassisBlock()), ROTATION_CHASSIS(new RadialChassisBlock()),
DRILL(new DrillBlock()), DRILL(new DrillBlock()),
DRILL_HEAD(new DrillHeadBlock()), DRILL_HEAD(new DrillHeadBlock()),
SAW(new SawBlock()), SAW(new SawBlock()),
@ -209,6 +211,8 @@ public enum AllBlocks {
POLISHED_DOLOMITE(new Block(Properties.from(DOLOMITE.block))), POLISHED_DOLOMITE(new Block(Properties.from(DOLOMITE.block))),
DOLOMITE_PILLAR(new RotatedPillarBlock(Properties.from(DOLOMITE.block))), DOLOMITE_PILLAR(new RotatedPillarBlock(Properties.from(DOLOMITE.block))),
VOLCANIC_ROCK(new VolcanicRockBlock()),
; ;
private enum ComesWith { private enum ComesWith {
@ -242,7 +246,9 @@ public enum AllBlocks {
alsoRegistered[i] = makeRelatedBlock(block, comesWith[i]); alsoRegistered[i] = makeRelatedBlock(block, comesWith[i]);
} }
public static void registerBlocks(IForgeRegistry<Block> registry) { public static void register(RegistryEvent.Register<Block> event) {
IForgeRegistry<Block> registry = event.getRegistry();
for (AllBlocks block : values()) { for (AllBlocks block : values()) {
if (block.get() == null) if (block.get() == null)
continue; continue;

View file

@ -22,8 +22,8 @@ import net.minecraft.inventory.container.ContainerType.IFactory;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.network.IContainerFactory; import net.minecraftforge.fml.network.IContainerFactory;
import net.minecraftforge.registries.IForgeRegistry;
public enum AllContainers { public enum AllContainers {
@ -32,7 +32,7 @@ public enum AllContainers {
FLEXCRATE(FlexcrateContainer::new), FLEXCRATE(FlexcrateContainer::new),
LOGISTICAL_INDEX(LogisticalIndexContainer::new), LOGISTICAL_INDEX(LogisticalIndexContainer::new),
LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new), LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new),
; ;
public ContainerType<? extends Container> type; public ContainerType<? extends Container> type;
@ -42,11 +42,11 @@ public enum AllContainers {
this.factory = factory; this.factory = factory;
} }
public static void registerContainers(IForgeRegistry<ContainerType<?>> iForgeRegistry) { public static void register(RegistryEvent.Register<ContainerType<?>> event) {
for (AllContainers container : values()) { for (AllContainers container : values()) {
container.type = new ContainerType<>(container.factory) container.type = new ContainerType<>(container.factory)
.setRegistryName(new ResourceLocation(Create.ID, Lang.asId(container.name()))); .setRegistryName(new ResourceLocation(Create.ID, Lang.asId(container.name())));
iForgeRegistry.register(container.type); event.getRegistry().register(container.type);
} }
} }

View file

@ -3,6 +3,7 @@ package com.simibubi.create;
import com.simibubi.create.foundation.item.IItemWithColorHandler; import com.simibubi.create.foundation.item.IItemWithColorHandler;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.IModule; 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.WrenchItem;
import com.simibubi.create.modules.contraptions.WrenchItemRenderer; import com.simibubi.create.modules.contraptions.WrenchItemRenderer;
import com.simibubi.create.modules.contraptions.relays.VerticalGearboxItem; import com.simibubi.create.modules.contraptions.relays.VerticalGearboxItem;
@ -32,6 +33,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.Rarity; import net.minecraft.item.Rarity;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; 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;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
@ -88,6 +90,7 @@ public enum AllItems {
DOUGH(ingredient()), DOUGH(ingredient()),
PROPELLER(ingredient()), PROPELLER(ingredient()),
WRENCH(new WrenchItem(standardItemProperties().setTEISR(() -> () -> renderUsing(AllItemRenderers.WRENCH)))), WRENCH(new WrenchItem(standardItemProperties().setTEISR(() -> () -> renderUsing(AllItemRenderers.WRENCH)))),
GOGGLES(new GogglesItem(standardItemProperties())),
CRUSHED_IRON(ingredient()), CRUSHED_IRON(ingredient()),
CRUSHED_GOLD(ingredient()), CRUSHED_GOLD(ingredient()),
@ -146,12 +149,16 @@ public enum AllItems {
return new Item(standardItemProperties().rarity(rarity)); return new Item(standardItemProperties().rarity(rarity));
} }
public static void registerItems(IForgeRegistry<Item> iForgeRegistry) { public static void register(RegistryEvent.Register<Item> event) {
IForgeRegistry<Item> registry = event.getRegistry();
for (AllItems item : values()) { for (AllItems item : values()) {
if (item.get() == null) if (item.get() == null)
continue; continue;
iForgeRegistry.register(item.get()); registry.register(item.get());
} }
AllBlocks.registerItemBlocks(registry);
} }
public Item get() { public Item get() {

View file

@ -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 <D extends IParticleData> AllParticles(Supplier<? extends ParticleType<D>> typeFactory,
IParticleMetaFactory<D> particleFactory) {
String asId = Lang.asId(this.name().toLowerCase());
entry = new ParticleEntry<D>(new ResourceLocation(Create.ID, asId), typeFactory, particleFactory);
}
public static void register(RegistryEvent.Register<ParticleType<?>> 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<D extends IParticleData> {
Supplier<? extends ParticleType<D>> typeFactory;
IParticleMetaFactory<D> particleFactory;
ParticleType<D> type;
ResourceLocation id;
public ParticleEntry(ResourceLocation id, Supplier<? extends ParticleType<D>> typeFactory,
IParticleMetaFactory<D> particleFactory) {
this.id = id;
this.typeFactory = typeFactory;
this.particleFactory = particleFactory;
}
ParticleType<?> getType() {
makeType();
return type;
}
void register(IForgeRegistry<ParticleType<?>> 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);
}
}
}

View file

@ -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.SawTileEntityRenderer;
import com.simibubi.create.modules.contraptions.receivers.TurntableTileEntity; 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.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntity; import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntityRenderer;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer; 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.MechanicalCrafterTileEntity;
import com.simibubi.create.modules.contraptions.receivers.crafter.MechanicalCrafterTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.crafter.MechanicalCrafterTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.ClutchTileEntity; import com.simibubi.create.modules.contraptions.relays.ClutchTileEntity;
@ -81,8 +81,8 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.registries.IForgeRegistry;
public enum AllTileEntities { public enum AllTileEntities {
@ -153,7 +153,7 @@ public enum AllTileEntities {
return te.getType().equals(type); return te.getType().equals(type);
} }
public static void registerTileEntities(IForgeRegistry<TileEntityType<?>> registry) { public static void register(RegistryEvent.Register<TileEntityType<?>> event) {
for (AllTileEntities tileEntity : values()) { for (AllTileEntities tileEntity : values()) {
Block[] blocks = new Block[tileEntity.blocks.length]; Block[] blocks = new Block[tileEntity.blocks.length];
for (int i = 0; i < blocks.length; i++) 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())); ResourceLocation resourceLocation = new ResourceLocation(Create.ID, Lang.asId(tileEntity.name()));
tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null) tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null)
.setRegistryName(resourceLocation); .setRegistryName(resourceLocation);
registry.register(tileEntity.type); event.getRegistry().register(tileEntity.type);
} }
} }

View file

@ -5,7 +5,7 @@ import org.apache.logging.log4j.Logger;
import com.simibubi.create.modules.ModuleLoadedCondition; import com.simibubi.create.modules.ModuleLoadedCondition;
import com.simibubi.create.modules.contraptions.TorquePropagator; 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.FrequencyHandler;
import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler; import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler;
import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler; 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.Item;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.particles.ParticleType;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.village.PointOfInterestType; import net.minecraft.village.PointOfInterestType;
import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.CraftingHelper;
@ -51,14 +52,17 @@ public class Create {
public Create() { public Create() {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
modEventBus.addListener(Create::init); modEventBus.addListener(Create::init);
modEventBus.addGenericListener(Block.class, Create::registerBlocks);
modEventBus.addGenericListener(Item.class, Create::registerItems); modEventBus.addGenericListener(Block.class, AllBlocks::register);
modEventBus.addGenericListener(IRecipeSerializer.class, Create::registerRecipes); modEventBus.addGenericListener(Item.class, AllItems::register);
modEventBus.addGenericListener(TileEntityType.class, Create::registerTileEntities); modEventBus.addGenericListener(IRecipeSerializer.class, AllRecipes::register);
modEventBus.addGenericListener(ContainerType.class, Create::registerContainers); modEventBus.addGenericListener(TileEntityType.class, AllTileEntities::register);
modEventBus.addGenericListener(ContainerType.class, AllContainers::register);
modEventBus.addGenericListener(VillagerProfession.class, Create::registerVillagerProfessions); modEventBus.addGenericListener(VillagerProfession.class, Create::registerVillagerProfessions);
modEventBus.addGenericListener(PointOfInterestType.class, Create::registerPointsOfInterest); 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); modEventBus.addListener(Create::createConfigs);
CreateClient.addListeners(modEventBus); CreateClient.addListeners(modEventBus);
@ -77,31 +81,6 @@ public class Create {
AllPackets.registerPackets(); AllPackets.registerPackets();
} }
public static void registerItems(RegistryEvent.Register<Item> event) {
AllItems.registerItems(event.getRegistry());
AllBlocks.registerItemBlocks(event.getRegistry());
}
public static void registerBlocks(RegistryEvent.Register<Block> event) {
AllBlocks.registerBlocks(event.getRegistry());
}
public static void registerTileEntities(RegistryEvent.Register<TileEntityType<?>> event) {
AllTileEntities.registerTileEntities(event.getRegistry());
}
public static void registerContainers(RegistryEvent.Register<ContainerType<?>> event) {
AllContainers.registerContainers(event.getRegistry());
}
public static void registerRecipes(RegistryEvent.Register<IRecipeSerializer<?>> event) {
AllRecipes.register(event);
}
public static void registerEntities(final RegistryEvent.Register<EntityType<?>> event) {
AllEntities.register(event);
}
public static void registerVillagerProfessions(RegistryEvent.Register<VillagerProfession> event) { public static void registerVillagerProfessions(RegistryEvent.Register<VillagerProfession> event) {
LogisticianHandler.registerVillagerProfessions(event); LogisticianHandler.registerVillagerProfessions(event);
} }

View file

@ -1,11 +1,15 @@
package com.simibubi.create; package com.simibubi.create;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import com.simibubi.create.foundation.block.CTModel; 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.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.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.modules.contraptions.WrenchModel; import com.simibubi.create.modules.contraptions.WrenchModel;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; 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.SchematicHandler;
import com.simibubi.create.modules.schematics.client.SchematicHologram; import com.simibubi.create.modules.schematics.client.SchematicHologram;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes; import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.IBakedModel;
@ -58,6 +63,7 @@ public class CreateClient {
modEventBus.addListener(CreateClient::onModelBake); modEventBus.addListener(CreateClient::onModelBake);
modEventBus.addListener(CreateClient::onModelRegistry); modEventBus.addListener(CreateClient::onModelRegistry);
modEventBus.addListener(CreateClient::onTextureStitch); modEventBus.addListener(CreateClient::onTextureStitch);
modEventBus.addListener(AllParticles::registerFactories);
}); });
} }
@ -103,9 +109,11 @@ public class CreateClient {
if (!event.getMap().getBasePath().equals("textures")) if (!event.getMap().getBasePath().equals("textures"))
return; return;
for (AllBlocks allBlocks : AllBlocks.values()) { for (AllBlocks allBlocks : AllBlocks.values()) {
if (!(allBlocks.get() instanceof IHaveConnectedTextures)) Block block = allBlocks.get();
if (!(block instanceof IHaveConnectedTextures))
continue; 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<ResourceLocation, IBakedModel> modelRegistry = event.getModelRegistry(); Map<ResourceLocation, IBakedModel> modelRegistry = event.getModelRegistry();
for (AllBlocks allBlocks : AllBlocks.values()) { for (AllBlocks allBlocks : AllBlocks.values()) {
if (!(allBlocks.get() instanceof IHaveConnectedTextures)) Block block = allBlocks.get();
if (block == null)
continue; continue;
swapModels(modelRegistry, getBlockModelLocation(allBlocks, ""),
t -> new CTModel(t, Lang.asId(allBlocks.name()))); List<ModelResourceLocation> 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), swapModels(modelRegistry, getItemModelLocation(AllItems.SYMMETRY_WAND),
@ -151,10 +166,21 @@ public class CreateClient {
ModelLoader.addSpecialModel(new ResourceLocation(Create.ID, "item/" + location)); ModelLoader.addSpecialModel(new ResourceLocation(Create.ID, "item/" + location));
} }
@OnlyIn(Dist.CLIENT)
protected static ModelResourceLocation getItemModelLocation(AllItems item) { protected static ModelResourceLocation getItemModelLocation(AllItems item) {
return new ModelResourceLocation(item.item.getRegistryName(), "inventory"); return new ModelResourceLocation(item.item.getRegistryName(), "inventory");
} }
@OnlyIn(Dist.CLIENT)
protected static List<ModelResourceLocation> getAllBlockStateModelLocations(AllBlocks block) {
List<ModelResourceLocation> 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) { protected static ModelResourceLocation getBlockModelLocation(AllBlocks block, String suffix) {
return new ModelResourceLocation(block.block.getRegistryName(), suffix); return new ModelResourceLocation(block.block.getRegistryName(), suffix);
} }
@ -165,4 +191,12 @@ public class CreateClient {
modelRegistry.put(location, factory.apply(modelRegistry.get(location))); modelRegistry.put(location, factory.apply(modelRegistry.get(location)));
} }
@OnlyIn(Dist.CLIENT)
protected static <T extends IBakedModel> void swapModels(Map<ResourceLocation, IBakedModel> modelRegistry,
List<ModelResourceLocation> locations, Function<IBakedModel, T> factory) {
locations.forEach(location -> {
swapModels(modelRegistry, location, factory);
});
}
} }

View file

@ -164,8 +164,8 @@ public class CreateConfig {
.translation(basePath + name).defineInRange(name, 20, 1, Integer.MAX_VALUE); .translation(basePath + name).defineInRange(name, 20, 1, Integer.MAX_VALUE);
name = "extractorInventoryScanDelay"; name = "extractorInventoryScanDelay";
extractorInventoryScanDelay = builder extractorInventoryScanDelay = builder.comment("",
.comment("", "The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.") "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); .translation(basePath + name).defineInRange(name, 40, 1, Integer.MAX_VALUE);
name = "extractorAmount"; name = "extractorAmount";
@ -348,7 +348,7 @@ public class CreateConfig {
.translation(basePath + name).defineInRange(name, 32D, 0D, 4096D); .translation(basePath + name).defineInRange(name, 32D, 0D, 4096D);
name = "fastSpeed"; 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); .translation(basePath + name).defineInRange(name, 512D, 0D, 65535D);
name = "mediumStressImpact"; name = "mediumStressImpact";

View file

@ -1,7 +1,7 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.foundation.block.SpriteShifter; 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.client.resources.ReloadListener;
import net.minecraft.profiler.IProfiler; import net.minecraft.profiler.IProfiler;

View file

@ -24,7 +24,7 @@ import net.minecraftforge.client.model.data.ModelProperty;
public class CTModel extends BakedModelWrapper<IBakedModel> { public class CTModel extends BakedModelWrapper<IBakedModel> {
private static ModelProperty<CTData> CT_PROPERTY = new ModelProperty<>(); private static ModelProperty<CTData> CT_PROPERTY = new ModelProperty<>();
private SpriteShiftEntry texture; private Iterable<SpriteShiftEntry> textures;
private class CTData { private class CTData {
int[] textures; int[] textures;
@ -43,9 +43,9 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
} }
} }
public CTModel(IBakedModel originalModel, String blockId) { public CTModel(IBakedModel originalModel, IHaveConnectedTextures block) {
super(originalModel); super(originalModel);
texture = SpriteShifter.getCT(blockId); textures = block.getSpriteShifts();
} }
@Override @Override
@ -74,9 +74,20 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
BakedQuad quad = quads.get(i); BakedQuad quad = quads.get(i);
if (!texDef.appliesTo(quad)) if (!texDef.appliesTo(quad))
continue; 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()); int index = data.get(quad.getFace());
if (index == -1) if (index == -1)
return quads; continue;
float textureSize = 16f / 128f / 8f; float textureSize = 16f / 128f / 8f;
float uShift = (index % 8) * textureSize; float uShift = (index % 8) * textureSize;

View file

@ -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<IBakedModel> {
private IBlockWithColoredVertices colorer;
private static ModelProperty<BlockPos> 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<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData extraData) {
List<BakedQuad> 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;
}
}

View file

@ -0,0 +1,7 @@
package com.simibubi.create.foundation.block;
public interface IBlockWithColoredVertices {
public int getColor(float x, float y, float z);
}

View file

@ -2,6 +2,10 @@ package com.simibubi.create.foundation.block;
import java.util.function.BiPredicate; 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.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@ -20,7 +24,9 @@ public interface IHaveConnectedTextures {
} }
@OnlyIn(Dist.CLIENT) @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, default boolean connectsTo(BlockState state, BlockState other, IEnviromentBlockReader reader, BlockPos pos,
BlockPos otherPos, Direction face) { BlockPos otherPos, Direction face) {
@ -34,6 +40,10 @@ public interface IHaveConnectedTextures {
return state.getBlock() == other.getBlock(); return state.getBlock() == other.getBlock();
} }
default Iterable<SpriteShiftEntry> getSpriteShifts() {
return ImmutableList.of(SpriteShifter.getCT(((Block) this).getRegistryName().getPath()));
}
default int getTextureIndex(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face) { default int getTextureIndex(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face) {
return getTextureIndexForContext(reader, pos, state, face, buildContext(reader, pos, state, 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); 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(); CTContext context = new CTContext();
context.up = connection.test(0, 1);
context.down = connection.test(0, -1); context.up = flip ? down : up;
context.left = connection.test(-1, 0); context.down = flip ? up : down;
context.right = connection.test(1, 0); context.left = flip ? right : left;
context.topLeft = connection.test(-1, 1); context.right = flip ? left : right;
context.topRight = connection.test(1, 1); context.topLeft = flip ? bottomRight : topLeft;
context.bottomLeft = connection.test(-1, -1); context.topRight = flip ? bottomLeft : topRight;
context.bottomRight = connection.test(1, -1); context.bottomLeft = flip ? topRight : bottomLeft;
context.bottomRight = flip ? topLeft : bottomRight;
return context; return context;
} }
default boolean shouldFlipUVs(BlockState state, Direction face) {
return false;
}
default int getTextureIndexForContext(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face, default int getTextureIndexForContext(IEnviromentBlockReader reader, BlockPos pos, BlockState state, Direction face,
CTContext c) { CTContext c) {
int tileX = 0, tileY = 0; int tileX = 0, tileY = 0;

View file

@ -24,11 +24,19 @@ public class SpriteShifter {
target = textureMap.getSprite(targetTextureLocation); target = textureMap.getSprite(targetTextureLocation);
} }
public ResourceLocation getTargetResourceLocation() {
return targetTextureLocation;
}
public TextureAtlasSprite getTarget() { public TextureAtlasSprite getTarget() {
if (target == null)
loadTextures();
return target; return target;
} }
public TextureAtlasSprite getOriginal() { public TextureAtlasSprite getOriginal() {
if (original == null)
loadTextures();
return original; return original;
} }
} }
@ -47,7 +55,6 @@ public class SpriteShifter {
SpriteShiftEntry entry = new SpriteShiftEntry(); SpriteShiftEntry entry = new SpriteShiftEntry();
entry.originalTextureLocation = new ResourceLocation(Create.ID, originalLocation); entry.originalTextureLocation = new ResourceLocation(Create.ID, originalLocation);
entry.targetTextureLocation = new ResourceLocation(Create.ID, targetLocation); entry.targetTextureLocation = new ResourceLocation(Create.ID, targetLocation);
entry.loadTextures();
textures.put(key, entry); textures.put(key, entry);
return entry; return entry;
} }

View file

@ -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<ItemStack> 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;
}
}

View file

@ -3,6 +3,8 @@ package com.simibubi.create.modules.contraptions.base;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
public abstract class GeneratingKineticTileEntity extends KineticTileEntity { public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
@ -24,6 +26,14 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
float speed = getGeneratedSpeed(); float speed = getGeneratedSpeed();
if (this.speed != speed) { 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 (speed == 0) {
if (hasSource()) if (hasSource())
notifyStressCapacityChange(0); notifyStressCapacityChange(0);

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.base; package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.CreateConfig;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
@ -18,6 +20,17 @@ public interface IRotate {
return this == NONE ? TextFormatting.GREEN return this == NONE ? TextFormatting.GREEN
: this == MEDIUM ? TextFormatting.AQUA : TextFormatting.LIGHT_PURPLE; : 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 { public enum StressImpact {

View file

@ -6,6 +6,8 @@ import com.simibubi.create.modules.contraptions.RotationPropagator;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.PushReaction; import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@ -79,4 +81,24 @@ public abstract class KineticBlock extends Block implements IRotate {
return false; 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;
}
} }

View file

@ -12,10 +12,13 @@ import java.util.UUID;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.SyncedTileEntity; 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.KineticNetwork;
import com.simibubi.create.modules.contraptions.RotationPropagator; import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; 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.block.BlockState;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
@ -24,11 +27,16 @@ import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue; import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity { public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity {
int particleSpawnCountdown;
// Speed related // Speed related
public float speed; public float speed;
protected Optional<BlockPos> source; protected Optional<BlockPos> source;
@ -254,6 +262,10 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
if (world.isRemote) if (world.isRemote)
return; return;
if (particleSpawnCountdown > 0)
if (--particleSpawnCountdown == 0)
spawnRotationIndicators();
if (initNetwork) { if (initNetwork) {
initNetwork = false; initNetwork = false;
@ -310,4 +322,53 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress); 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);
}
}
} }

View file

@ -134,4 +134,14 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
return state.get(HORIZONTAL_FACING).getAxis(); return state.get(HORIZONTAL_FACING).getAxis();
} }
@Override
public float getParticleTargetRadius() {
return 1.125f;
}
@Override
public float getParticleInitialRadius() {
return 1f;
}
} }

View file

@ -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<RotationIndicatorParticleData> {
public Type() {
super(false, RotationIndicatorParticleData.DESERIALIZER);
}
}
public static class Factory implements IParticleFactory<RotationIndicatorParticleData> {
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);
}
}
}

View file

@ -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<RotationIndicatorParticleData> DESERIALIZER = new IParticleData.IDeserializer<RotationIndicatorParticleData>() {
public RotationIndicatorParticleData deserialize(ParticleType<RotationIndicatorParticleData> 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<RotationIndicatorParticleData> 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);
}
}

View file

@ -167,5 +167,15 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock {
protected boolean hasStaticPart() { protected boolean hasStaticPart() {
return false; return false;
} }
@Override
public float getParticleTargetRadius() {
return 1.125f;
}
@Override
public float getParticleInitialRadius() {
return 1f;
}
} }

View file

@ -133,6 +133,16 @@ public class MechanicalMixerBlock extends KineticBlock
return tileEntity.currentValue; return tileEntity.currentValue;
} }
@Override
public float getParticleTargetRadius() {
return .85f;
}
@Override
public float getParticleInitialRadius() {
return .75f;
}
@Override @Override
public SpeedLevel getMinimumRequiredSpeedLevel() { public SpeedLevel getMinimumRequiredSpeedLevel() {
return SpeedLevel.MEDIUM; return SpeedLevel.MEDIUM;

View file

@ -43,9 +43,9 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class Contraption { public class Contraption {
protected Map<BlockPos, BlockInfo> blocks; public Map<BlockPos, BlockInfo> blocks;
protected List<MutablePair<BlockInfo, MovementContext>> actors; public List<MutablePair<BlockInfo, MovementContext>> actors;
protected AxisAlignedBB constructCollisionBox; public AxisAlignedBB constructCollisionBox;
protected Set<BlockPos> cachedColliders; protected Set<BlockPos> cachedColliders;
protected Direction cachedColliderDirection; protected Direction cachedColliderDirection;
protected BlockPos anchor; protected BlockPos anchor;
@ -74,9 +74,9 @@ public class Contraption {
return null; return null;
BlockState state = world.getBlockState(current); BlockState state = world.getBlockState(current);
if (!isChassis(state)) if (!isLinearChassis(state))
continue; continue;
if (!TranslationChassisBlock.sameKind(anchorChassis, state)) if (!LinearChassisBlock.sameKind(anchorChassis, state))
continue; continue;
if (state.get(AXIS) != axis) if (state.get(AXIS) != axis)
continue; continue;
@ -157,8 +157,11 @@ public class Contraption {
return true; return true;
if (!canPush(world, pos, direction)) if (!canPush(world, pos, direction))
return false; return false;
if (isChassis(state) && !moveChassis(world, pos, direction, frontier, visited)) if (isLinearChassis(state) && !moveLinearChassis(world, pos, direction, frontier, visited))
return false; return false;
if (isRadialChassis(state) && !moveRadialChassis(world, pos, direction, frontier, visited))
return false;
if (state.getBlock() instanceof SlimeBlock) if (state.getBlock() instanceof SlimeBlock)
for (Direction offset : Direction.values()) { for (Direction offset : Direction.values()) {
BlockPos offsetPos = pos.offset(offset); BlockPos offsetPos = pos.offset(offset);
@ -177,7 +180,7 @@ public class Contraption {
return true; return true;
} }
private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List<BlockPos> frontier, private boolean moveLinearChassis(World world, BlockPos pos, Direction movementDirection, List<BlockPos> frontier,
Set<BlockPos> visited) { Set<BlockPos> visited) {
List<BlockInfo> cluster = getChassisClusterAt(world, pos); List<BlockInfo> cluster = getChassisClusterAt(world, pos);
@ -223,7 +226,7 @@ public class Contraption {
BlockState chassisState = world.getBlockState(currentChassisPos); BlockState chassisState = world.getBlockState(currentChassisPos);
// Not attached to a chassis // Not attached to a chassis
if (!isChassis(chassisState) || chassisState.get(AXIS) != chassisAxis) if (!isLinearChassis(chassisState) || chassisState.get(AXIS) != chassisAxis)
continue; continue;
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state)
&& state.get(FACING) == chassisDirection.getOpposite()) && state.get(FACING) == chassisDirection.getOpposite())
@ -300,8 +303,96 @@ public class Contraption {
return true; return true;
} }
private static boolean isChassis(BlockState state) { private boolean moveRadialChassis(World world, BlockPos pos, Direction movementDirection, List<BlockPos> frontier,
return TranslationChassisBlock.isChassis(state); Set<BlockPos> visited) {
RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block;
List<BlockPos> 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<BlockPos> localFrontier = new LinkedList<>();
Set<BlockPos> 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) { 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) { protected static boolean canPush(World world, BlockPos pos, Direction direction) {
BlockState blockState = world.getBlockState(pos); BlockState blockState = world.getBlockState(pos);
if (isChassis(blockState)) if (isLinearChassis(blockState) || isRadialChassis(blockState))
return true; return true;
if (blockState.getBlock() instanceof ShulkerBoxBlock) if (blockState.getBlock() instanceof ShulkerBoxBlock)
return false; return false;
@ -365,7 +456,7 @@ public class Contraption {
MovementContext context = MovementContext.readNBT(comp); MovementContext context = MovementContext.readNBT(comp);
getActors().add(MutablePair.of(info, context)); getActors().add(MutablePair.of(info, context));
}); });
if (nbt.contains("BoundsFront")) if (nbt.contains("BoundsFront"))
constructCollisionBox = readAABB(nbt.getList("BoundsFront", 5)); constructCollisionBox = readAABB(nbt.getList("BoundsFront", 5));
@ -387,7 +478,7 @@ public class Contraption {
c.put("Data", block.nbt); c.put("Data", block.nbt);
blocks.add(c); blocks.add(c);
} }
ListNBT actorsNBT = new ListNBT(); ListNBT actorsNBT = new ListNBT();
for (MutablePair<BlockInfo, MovementContext> actor : getActors()) { for (MutablePair<BlockInfo, MovementContext> actor : getActors()) {
CompoundNBT compound = new CompoundNBT(); CompoundNBT compound = new CompoundNBT();

View file

@ -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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper; 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.block.BlockState;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;

View file

@ -1,6 +1,10 @@
package com.simibubi.create.modules.contraptions.receivers.constructs; package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllBlocks; 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.Block;
import net.minecraft.block.BlockState; 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;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos; 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_TOP = BooleanProperty.create("sticky_top");
public static final BooleanProperty STICKY_BOTTOM = BooleanProperty.create("sticky_bottom"); public static final BooleanProperty STICKY_BOTTOM = BooleanProperty.create("sticky_bottom");
public TranslationChassisBlock() { public LinearChassisBlock() {
super(Properties.from(Blocks.PISTON)); super(Properties.from(Blocks.PISTON));
setDefaultState(getDefaultState().with(STICKY_TOP, false).with(STICKY_BOTTOM, false)); setDefaultState(getDefaultState().with(STICKY_TOP, false).with(STICKY_BOTTOM, false));
} }
@ -45,7 +50,7 @@ public class TranslationChassisBlock extends AbstractChassisBlock {
return null; return null;
return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM; return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM;
} }
@Override @Override
public String getTranslationKey() { public String getTranslationKey() {
Block block = AllBlocks.TRANSLATION_CHASSIS.get(); Block block = AllBlocks.TRANSLATION_CHASSIS.get();
@ -62,4 +67,25 @@ public class TranslationChassisBlock extends AbstractChassisBlock {
return state1.getBlock() == state2.getBlock(); return state1.getBlock() == state2.getBlock();
} }
@Override
public Iterable<SpriteShiftEntry> 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);
}
} }

View file

@ -12,14 +12,14 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; 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_NORTH = BooleanProperty.create("sticky_north");
public static final BooleanProperty STICKY_SOUTH = BooleanProperty.create("sticky_south"); 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_EAST = BooleanProperty.create("sticky_east");
public static final BooleanProperty STICKY_WEST = BooleanProperty.create("sticky_west"); public static final BooleanProperty STICKY_WEST = BooleanProperty.create("sticky_west");
public RotationChassisBlock() { public RadialChassisBlock() {
super(Properties.from(Blocks.PISTON)); super(Properties.from(Blocks.PISTON));
setDefaultState(getDefaultState().with(STICKY_EAST, false).with(STICKY_SOUTH, false).with(STICKY_NORTH, false) setDefaultState(getDefaultState().with(STICKY_EAST, false).with(STICKY_SOUTH, false).with(STICKY_NORTH, false)
.with(STICKY_WEST, false)); .with(STICKY_WEST, false));
@ -30,16 +30,16 @@ public class RotationChassisBlock extends AbstractChassisBlock {
builder.add(STICKY_NORTH, STICKY_EAST, STICKY_SOUTH, STICKY_WEST); builder.add(STICKY_NORTH, STICKY_EAST, STICKY_SOUTH, STICKY_WEST);
super.fillStateContainer(builder); super.fillStateContainer(builder);
} }
@Override @Override
public String getValueName(BlockState state, IWorld world, BlockPos pos) { public String getValueName(BlockState state, IWorld world, BlockPos pos) {
return Lang.translate("generic.radius"); return Lang.translate("generic.radius");
} }
@Override @Override
public BooleanProperty getGlueableSide(BlockState state, Direction face) { public BooleanProperty getGlueableSide(BlockState state, Direction face) {
Axis axis = state.get(AXIS); Axis axis = state.get(AXIS);
if (axis == Axis.X) { if (axis == Axis.X) {
if (face == Direction.NORTH) if (face == Direction.NORTH)
return STICKY_WEST; return STICKY_WEST;
@ -50,7 +50,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.DOWN) if (face == Direction.DOWN)
return STICKY_SOUTH; return STICKY_SOUTH;
} }
if (axis == Axis.Y) { if (axis == Axis.Y) {
if (face == Direction.NORTH) if (face == Direction.NORTH)
return STICKY_NORTH; return STICKY_NORTH;
@ -61,7 +61,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.WEST) if (face == Direction.WEST)
return STICKY_WEST; return STICKY_WEST;
} }
if (axis == Axis.Z) { if (axis == Axis.Z) {
if (face == Direction.UP) if (face == Direction.UP)
return STICKY_NORTH; return STICKY_NORTH;
@ -72,7 +72,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.WEST) if (face == Direction.WEST)
return STICKY_WEST; return STICKY_WEST;
} }
return null; return null;
} }

View file

@ -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.foundation.block.IWithTileEntity;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;

View file

@ -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.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; 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.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;

View file

@ -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.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;

View file

@ -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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -11,6 +11,8 @@ import java.util.Set;
import com.simibubi.create.AllBlockTags; import com.simibubi.create.AllBlockTags;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateConfig; 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.BlockState;
import net.minecraft.block.PistonBlock; import net.minecraft.block.PistonBlock;
@ -87,7 +89,7 @@ public class RotationConstruct {
private List<BlockInfo> getAttachedBlocksByChassis(World world, Direction direction, List<BlockInfo> chassis) { private List<BlockInfo> getAttachedBlocksByChassis(World world, Direction direction, List<BlockInfo> chassis) {
List<BlockInfo> blocks = new ArrayList<>(); List<BlockInfo> blocks = new ArrayList<>();
RotationChassisBlock def = (RotationChassisBlock) AllBlocks.ROTATION_CHASSIS.block; RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block;
for (BlockInfo chassisBlock : chassis) { for (BlockInfo chassisBlock : chassis) {
blocks.add(chassisBlock); blocks.add(chassisBlock);

View file

@ -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; import java.nio.ByteBuffer;

View file

@ -25,6 +25,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
protected MountedContraption contraption; protected MountedContraption contraption;
protected float initialAngle; protected float initialAngle;
enum MovementType {
TRANSLATION, ROTATION, MOUNTED;
}
// Not synchronizing any of these // Not synchronizing any of these
public float targetYaw; public float targetYaw;

View file

@ -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.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;

View file

@ -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.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.foundation.block.ProperDirectionalBlock; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;

View file

@ -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.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.Arrays;
import java.util.Iterator; import java.util.Iterator;
@ -12,9 +12,10 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; 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.MovementContext;
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MoverType; 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.block.Blocks;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;

View file

@ -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.AllBlocks;
import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; 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.block.BlockState;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;

View file

@ -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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -8,6 +8,7 @@ import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption;
import net.minecraft.block.material.PushReaction; import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;

View file

@ -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.MECHANICAL_PISTON_HEAD;
import static com.simibubi.create.AllBlocks.PISTON_POLE; import static com.simibubi.create.AllBlocks.PISTON_POLE;
@ -10,7 +10,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; 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.block.BlockState;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;

View file

@ -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.AllBlocks;
import com.simibubi.create.CreateConfig; import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.ProperDirectionalBlock; 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.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -22,7 +22,6 @@ import net.minecraft.world.World;
public class PistonPoleBlock extends ProperDirectionalBlock { public class PistonPoleBlock extends ProperDirectionalBlock {
public PistonPoleBlock() { public PistonPoleBlock() {
super(Properties.from(Blocks.PISTON_HEAD)); super(Properties.from(Blocks.PISTON_HEAD));
setDefaultState(getDefaultState().with(FACING, Direction.UP)); setDefaultState(getDefaultState().with(FACING, Direction.UP));

View file

@ -40,7 +40,7 @@ public class MechanicalCrafterBlock extends DirectionalKineticBlock
public Axis getRotationAxis(BlockState state) { public Axis getRotationAxis(BlockState state) {
return state.get(FACING).getAxis(); return state.get(FACING).getAxis();
} }
@Override @Override
public BlockState getStateForPlacement(BlockItemUseContext context) { public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite()); 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 getDefaultState().with(FACING, blockState.get(FACING));
return super.getStateForPlacement(context); return super.getStateForPlacement(context);
} }
@Override @Override
public BlockRenderLayer getRenderLayer() { public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT_MIPPED; return BlockRenderLayer.CUTOUT_MIPPED;
} }
@Override
public float getParticleTargetRadius() {
return .85f;
}
@Override
public float getParticleInitialRadius() {
return .75f;
}
} }

View file

@ -74,6 +74,16 @@ public class CogWheelBlock extends ShaftBlock {
return isLarge ? LARGE_GEAR_Y : GEAR_Y; 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 // IRotate
@Override @Override

View file

@ -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; 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: // IRotate:
@Override @Override

View file

@ -37,20 +37,23 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
} }
@Override @Override
public <T> LazyOptional<T> getCapability(Capability<T> capabitily, Direction side) { public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction side) {
if (capabitily == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if (!this.cap.isPresent()) { if (!this.cap.isPresent()) {
if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) { if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) {
TileEntity teBelow = world.getTileEntity(pos.down()); TileEntity teBelow = world.getTileEntity(pos.down());
if (teBelow != null) if (teBelow != null) {
cap = LazyOptional.of(() -> teBelow.getCapability(capabitily, Direction.UP).orElse(null)) T capBelow = teBelow.getCapability(capability, Direction.UP).orElse(null);
.cast(); if (capBelow != null) {
cap = LazyOptional.of(() -> capBelow).cast();
}
}
} }
} }
return this.cap.cast(); return this.cap.cast();
} }
return super.getCapability(capabitily, side); return super.getCapability(capability, side);
} }
@Override @Override

View file

@ -21,7 +21,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
private int cooldown; private int cooldown;
private LazyOptional<IItemHandler> inventory; private LazyOptional<IItemHandler> inventory;
private boolean initialize; private boolean initialize;
public ExtractorTileEntity() { public ExtractorTileEntity() {
super(AllTileEntities.EXTRACTOR.type); super(AllTileEntities.EXTRACTOR.type);
state = State.ON_COOLDOWN; state = State.ON_COOLDOWN;
@ -29,12 +29,12 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
inventory = LazyOptional.empty(); inventory = LazyOptional.empty();
filter = ItemStack.EMPTY; filter = ItemStack.EMPTY;
} }
@Override @Override
public State getState() { public State getState() {
return state; return state;
} }
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
filter = ItemStack.read(compound.getCompound("Filter")); filter = ItemStack.read(compound.getCompound("Filter"));
@ -42,19 +42,19 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
setState(State.LOCKED); setState(State.LOCKED);
super.read(compound); super.read(compound);
} }
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
compound.put("Filter", filter.serializeNBT()); compound.put("Filter", filter.serializeNBT());
compound.putBoolean("Locked", getState() == State.LOCKED); compound.putBoolean("Locked", getState() == State.LOCKED);
return super.write(compound); return super.write(compound);
} }
@Override @Override
public void onLoad() { public void onLoad() {
initialize = true; initialize = true;
} }
@Override @Override
public void tick() { public void tick() {
if (initialize && hasWorld()) { if (initialize && hasWorld()) {
@ -65,7 +65,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
} }
IExtractor.super.tick(); IExtractor.super.tick();
} }
@Override @Override
public void setState(State state) { public void setState(State state) {
if (state == State.ON_COOLDOWN) if (state == State.ON_COOLDOWN)
@ -74,7 +74,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
cooldown = CreateConfig.parameters.extractorInventoryScanDelay.get(); cooldown = CreateConfig.parameters.extractorInventoryScanDelay.get();
this.state = state; this.state = state;
} }
@Override @Override
public int tickCooldown() { public int tickCooldown() {
return cooldown--; return cooldown--;

View file

@ -1,34 +1,20 @@
package com.simibubi.create.modules.palettes; package com.simibubi.create.modules.palettes;
import java.util.function.Supplier;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.block.IHaveConnectedTextures; import com.simibubi.create.foundation.block.IHaveConnectedTextures;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.GlassBlock; import net.minecraft.block.GlassBlock;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.ResourceLocation;
public class CTGlassBlock extends GlassBlock implements IHaveConnectedTextures { public class CTGlassBlock extends GlassBlock implements IHaveConnectedTextures {
private Supplier<ResourceLocation> textureToReplace;
private boolean hasAlpha; private boolean hasAlpha;
public CTGlassBlock(boolean hasAlpha) { public CTGlassBlock(boolean hasAlpha) {
super(Properties.from(Blocks.GLASS)); super(Properties.from(Blocks.GLASS));
textureToReplace = () -> {
return new ResourceLocation(Create.ID, "block/" + getRegistryName().getPath());
};
this.hasAlpha = hasAlpha; this.hasAlpha = hasAlpha;
} }
@Override
public boolean appliesTo(BakedQuad quad) {
return quad.getSprite().getName().equals(textureToReplace.get());
}
@Override @Override
public BlockRenderLayer getRenderLayer() { public BlockRenderLayer getRenderLayer() {
return hasAlpha ? BlockRenderLayer.TRANSLUCENT : super.getRenderLayer(); return hasAlpha ? BlockRenderLayer.TRANSLUCENT : super.getRenderLayer();

View file

@ -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;
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/volcanic_rock" }
}
}

View file

@ -14,6 +14,7 @@
"item.create.blueprint_and_quill": "Schematic and Quill", "item.create.blueprint_and_quill": "Schematic and Quill",
"item.create.blueprint": "Schematic", "item.create.blueprint": "Schematic",
"item.create.belt_connector": "Mechanical Belt", "item.create.belt_connector": "Mechanical Belt",
"item.create.goggles": "Engineer's Goggles",
"item.create.filter": "Filter", "item.create.filter": "Filter",
"item.create.rose_quartz": "Rose Quartz", "item.create.rose_quartz": "Rose Quartz",
"item.create.refined_rose_quartz": "Refined Rose Quartz", "item.create.refined_rose_quartz": "Refined Rose Quartz",
@ -78,8 +79,8 @@
"block.create.mechanical_piston_head": "Mechanical Piston Head", "block.create.mechanical_piston_head": "Mechanical Piston Head",
"block.create.piston_pole": "Piston Extension Pole", "block.create.piston_pole": "Piston Extension Pole",
"block.create.mechanical_bearing": "Mechanical Bearing", "block.create.mechanical_bearing": "Mechanical Bearing",
"block.create.translation_chassis": "Translation Chassis", "block.create.translation_chassis": "Linear Chassis",
"block.create.rotation_chassis": "Rotation Chassis", "block.create.rotation_chassis": "Radial Chassis",
"block.create.contact": "Redstone Contact", "block.create.contact": "Redstone Contact",
"block.create.redstone_bridge": "Redstone Link", "block.create.redstone_bridge": "Redstone Link",
@ -107,6 +108,8 @@
"block.create.diorite_bricks": "Diorite Bricks", "block.create.diorite_bricks": "Diorite Bricks",
"block.create.granite_bricks": "Granite Bricks", "block.create.granite_bricks": "Granite Bricks",
"block.create.volcanic_rock": "Basalt",
"block.create.gabbro": "Gabbro", "block.create.gabbro": "Gabbro",
"block.create.gabbro_stairs": "Gabbro Stairs", "block.create.gabbro_stairs": "Gabbro Stairs",
"block.create.gabbro_slab": "Gabbro Slab", "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.control2": "R-Click while Sneaking",
"item.create.belt_connector.tooltip.action2": "_Resets_ the first selected position for the Belt", "item.create.belt_connector.tooltip.action2": "_Resets_ the first selected position for the Belt",
"block.create.belt_support.tooltip": "BELT SUPPORT", "item.create.goggles.tooltip": "GOGGLES",
"block.create.belt_support.tooltip.summary": "A _purely_ _decorational_ block suitable for mounting _Mechanical_ _Belts_ to the Ground.", "item.create.goggles.tooltip.summary": "A pair of glasses to augment your vision with useful _kinetic_ _information._",
"block.create.belt_support.tooltip.condition1": "When placed below a Belt", "item.create.goggles.tooltip.condition1": "When worn",
"block.create.belt_support.tooltip.behaviour1": "Supports the top of the Belt, hiding the bottom layer.", "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": "MOTOR",
"block.create.motor.tooltip.summary": "A configurable source of _Rotational_ _Force_", "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.behaviour1": "_Starts_ to compress items dropped below it.",
"block.create.mechanical_press.tooltip.condition2": "When Above a Mechanical Belt", "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_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": "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.", "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.",

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/volcanic_rock"
}
}

View file

@ -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]
}
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "create:block/palettes/volcanic_rock"
}

View file

@ -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"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

View file

@ -1,19 +0,0 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "create:belt_support"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -1,26 +0,0 @@
{
"type": "crafting_shaped",
"pattern": [
"N",
"P",
"P"
],
"key": {
"N": {
"item": "create:gold_sheet"
},
"P": {
"tag": "minecraft:planks"
}
},
"result": {
"item": "create:belt_support",
"count": 4
},
"conditions": [
{
"type": "create:module",
"module": "logistics"
}
]
}

View file

@ -0,0 +1,16 @@
{
"type": "create:pressing",
"group": "minecraft:misc",
"ingredients": [
{
"item": "minecraft:sugar_cane"
}
],
"results": [
{
"item": "minecraft:paper",
"count": 1
}
],
"processingTime": 100
}