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

View file

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

View file

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

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

View file

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

View file

@ -1,11 +1,15 @@
package com.simibubi.create;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.simibubi.create.foundation.block.CTModel;
import com.simibubi.create.foundation.block.ColoredVertexModel;
import com.simibubi.create.foundation.block.IBlockWithColoredVertices;
import com.simibubi.create.foundation.block.IHaveConnectedTextures;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
import com.simibubi.create.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.modules.contraptions.WrenchModel;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
@ -20,6 +24,7 @@ import com.simibubi.create.modules.schematics.client.SchematicAndQuillHandler;
import com.simibubi.create.modules.schematics.client.SchematicHandler;
import com.simibubi.create.modules.schematics.client.SchematicHologram;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.model.IBakedModel;
@ -58,6 +63,7 @@ public class CreateClient {
modEventBus.addListener(CreateClient::onModelBake);
modEventBus.addListener(CreateClient::onModelRegistry);
modEventBus.addListener(CreateClient::onTextureStitch);
modEventBus.addListener(AllParticles::registerFactories);
});
}
@ -103,9 +109,11 @@ public class CreateClient {
if (!event.getMap().getBasePath().equals("textures"))
return;
for (AllBlocks allBlocks : AllBlocks.values()) {
if (!(allBlocks.get() instanceof IHaveConnectedTextures))
Block block = allBlocks.get();
if (!(block instanceof IHaveConnectedTextures))
continue;
event.addSprite(new ResourceLocation(Create.ID, "block/connected/" + Lang.asId(allBlocks.name())));
for (SpriteShiftEntry spriteShiftEntry : ((IHaveConnectedTextures) block).getSpriteShifts())
event.addSprite(spriteShiftEntry.getTargetResourceLocation());
}
}
@ -114,10 +122,17 @@ public class CreateClient {
Map<ResourceLocation, IBakedModel> modelRegistry = event.getModelRegistry();
for (AllBlocks allBlocks : AllBlocks.values()) {
if (!(allBlocks.get() instanceof IHaveConnectedTextures))
Block block = allBlocks.get();
if (block == null)
continue;
swapModels(modelRegistry, getBlockModelLocation(allBlocks, ""),
t -> new CTModel(t, Lang.asId(allBlocks.name())));
List<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),
@ -151,10 +166,21 @@ public class CreateClient {
ModelLoader.addSpecialModel(new ResourceLocation(Create.ID, "item/" + location));
}
@OnlyIn(Dist.CLIENT)
protected static ModelResourceLocation getItemModelLocation(AllItems item) {
return new ModelResourceLocation(item.item.getRegistryName(), "inventory");
}
@OnlyIn(Dist.CLIENT)
protected static List<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) {
return new ModelResourceLocation(block.block.getRegistryName(), suffix);
}
@ -165,4 +191,12 @@ public class CreateClient {
modelRegistry.put(location, factory.apply(modelRegistry.get(location)));
}
@OnlyIn(Dist.CLIENT)
protected static <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);
name = "extractorInventoryScanDelay";
extractorInventoryScanDelay = builder
.comment("", "The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.")
extractorInventoryScanDelay = builder.comment("",
"The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.")
.translation(basePath + name).defineInRange(name, 40, 1, Integer.MAX_VALUE);
name = "extractorAmount";
@ -348,7 +348,7 @@ public class CreateConfig {
.translation(basePath + name).defineInRange(name, 32D, 0D, 4096D);
name = "fastSpeed";
mediumSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'fast'")
fastSpeed = builder.comment("", "[in Degrees/Tick]", "Minimum speed of rotation to be considered 'fast'")
.translation(basePath + name).defineInRange(name, 512D, 0D, 65535D);
name = "mediumStressImpact";

View file

@ -1,7 +1,7 @@
package com.simibubi.create;
import com.simibubi.create.foundation.block.SpriteShifter;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer;
import com.simibubi.create.modules.contraptions.receivers.constructs.bearing.MechanicalBearingTileEntityRenderer;
import net.minecraft.client.resources.ReloadListener;
import net.minecraft.profiler.IProfiler;

View file

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

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

View file

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

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.UUID;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import net.minecraft.tileentity.TileEntityType;
public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
@ -24,6 +26,14 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
float speed = getGeneratedSpeed();
if (this.speed != speed) {
if (!world.isRemote) {
SpeedLevel levelBefore = SpeedLevel.of(this.speed);
SpeedLevel levelafter = SpeedLevel.of(speed);
if (levelBefore != levelafter)
queueRotationIndicators();
}
if (speed == 0) {
if (hasSource())
notifyStressCapacityChange(0);

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.CreateConfig;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemUseContext;
import net.minecraft.util.ActionResultType;
@ -18,6 +20,17 @@ public interface IRotate {
return this == NONE ? TextFormatting.GREEN
: this == MEDIUM ? TextFormatting.AQUA : TextFormatting.LIGHT_PURPLE;
}
public static SpeedLevel of(float speed) {
speed = Math.abs(speed);
if (speed >= CreateConfig.parameters.fastSpeed.get()) {
return FAST;
} else if (speed >= CreateConfig.parameters.mediumSpeed.get()) {
return MEDIUM;
}
return NONE;
}
}
public enum StressImpact {

View file

@ -6,6 +6,8 @@ import com.simibubi.create.modules.contraptions.RotationPropagator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
@ -79,4 +81,24 @@ public abstract class KineticBlock extends Block implements IRotate {
return false;
}
@Override
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (tileEntity == null || !(tileEntity instanceof KineticTileEntity))
return;
if (worldIn.isRemote)
return;
KineticTileEntity kte = (KineticTileEntity) tileEntity;
kte.queueRotationIndicators();
}
public float getParticleTargetRadius() {
return .65f;
}
public float getParticleInitialRadius() {
return .75f;
}
}

View file

@ -12,10 +12,13 @@ import java.util.UUID;
import com.simibubi.create.Create;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.KineticNetwork;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
@ -24,11 +27,16 @@ import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity {
int particleSpawnCountdown;
// Speed related
public float speed;
protected Optional<BlockPos> source;
@ -254,6 +262,10 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
if (world.isRemote)
return;
if (particleSpawnCountdown > 0)
if (--particleSpawnCountdown == 0)
spawnRotationIndicators();
if (initNetwork) {
initNetwork = false;
@ -310,4 +322,53 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress);
}
public void queueRotationIndicators() {
// wait a few ticks for network jamming etc
particleSpawnCountdown = 2;
}
protected void spawnRotationIndicators() {
if (getSpeed() == 0)
return;
BlockState state = getBlockState();
Block block = state.getBlock();
if (!(block instanceof KineticBlock))
return;
KineticBlock kb = (KineticBlock) block;
float radius1 = kb.getParticleInitialRadius();
float radius2 = kb.getParticleTargetRadius();
Axis axis = kb.getRotationAxis(state);
if (axis == null)
return;
char axisChar = axis.name().charAt(0);
Vec3d vec = VecHelper.getCenterOf(pos);
int color = 0x22FF22;
int particleSpeed = 10;
switch (SpeedLevel.of(getSpeed())) {
case FAST:
color = 16733695;
particleSpeed = 30;
break;
case MEDIUM:
color = 0x0084FF;
particleSpeed = 20;
break;
default:
break;
}
particleSpeed *= Math.signum(getSpeed());
if (getWorld() instanceof ServerWorld) {
RotationIndicatorParticleData particleData = new RotationIndicatorParticleData(color, particleSpeed,
radius1, radius2, 10, axisChar);
((ServerWorld) getWorld()).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1);
}
}
}

View file

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

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() {
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;
}
@Override
public float getParticleTargetRadius() {
return .85f;
}
@Override
public float getParticleInitialRadius() {
return .75f;
}
@Override
public SpeedLevel getMinimumRequiredSpeedLevel() {
return SpeedLevel.MEDIUM;

View file

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

View file

@ -1,6 +1,10 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveConnectedTextures;
import com.simibubi.create.foundation.block.SpriteShifter;
import com.simibubi.create.foundation.block.SpriteShifter.SpriteShiftEntry;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -11,13 +15,14 @@ import net.minecraft.state.StateContainer.Builder;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IEnviromentBlockReader;
public class TranslationChassisBlock extends AbstractChassisBlock {
public class LinearChassisBlock extends AbstractChassisBlock implements IHaveConnectedTextures {
public static final BooleanProperty STICKY_TOP = BooleanProperty.create("sticky_top");
public static final BooleanProperty STICKY_BOTTOM = BooleanProperty.create("sticky_bottom");
public TranslationChassisBlock() {
public LinearChassisBlock() {
super(Properties.from(Blocks.PISTON));
setDefaultState(getDefaultState().with(STICKY_TOP, false).with(STICKY_BOTTOM, false));
}
@ -45,7 +50,7 @@ public class TranslationChassisBlock extends AbstractChassisBlock {
return null;
return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM;
}
@Override
public String getTranslationKey() {
Block block = AllBlocks.TRANSLATION_CHASSIS.get();
@ -62,4 +67,25 @@ public class TranslationChassisBlock extends AbstractChassisBlock {
return state1.getBlock() == state2.getBlock();
}
@Override
public Iterable<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.world.IWorld;
public class RotationChassisBlock extends AbstractChassisBlock {
public class RadialChassisBlock extends AbstractChassisBlock {
public static final BooleanProperty STICKY_NORTH = BooleanProperty.create("sticky_north");
public static final BooleanProperty STICKY_SOUTH = BooleanProperty.create("sticky_south");
public static final BooleanProperty STICKY_EAST = BooleanProperty.create("sticky_east");
public static final BooleanProperty STICKY_WEST = BooleanProperty.create("sticky_west");
public RotationChassisBlock() {
public RadialChassisBlock() {
super(Properties.from(Blocks.PISTON));
setDefaultState(getDefaultState().with(STICKY_EAST, false).with(STICKY_SOUTH, false).with(STICKY_NORTH, false)
.with(STICKY_WEST, false));
@ -30,16 +30,16 @@ public class RotationChassisBlock extends AbstractChassisBlock {
builder.add(STICKY_NORTH, STICKY_EAST, STICKY_SOUTH, STICKY_WEST);
super.fillStateContainer(builder);
}
@Override
public String getValueName(BlockState state, IWorld world, BlockPos pos) {
return Lang.translate("generic.radius");
}
@Override
public BooleanProperty getGlueableSide(BlockState state, Direction face) {
Axis axis = state.get(AXIS);
if (axis == Axis.X) {
if (face == Direction.NORTH)
return STICKY_WEST;
@ -50,7 +50,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.DOWN)
return STICKY_SOUTH;
}
if (axis == Axis.Y) {
if (face == Direction.NORTH)
return STICKY_NORTH;
@ -61,7 +61,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.WEST)
return STICKY_WEST;
}
if (axis == Axis.Z) {
if (face == Direction.UP)
return STICKY_NORTH;
@ -72,7 +72,7 @@ public class RotationChassisBlock extends AbstractChassisBlock {
if (face == Direction.WEST)
return STICKY_WEST;
}
return null;
}

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

View file

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

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.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.CreateConfig;
import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;

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

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

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

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.PISTON_POLE;
@ -10,7 +10,8 @@ import java.util.ArrayList;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption;
import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;

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

View file

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

View file

@ -74,6 +74,16 @@ public class CogWheelBlock extends ShaftBlock {
return isLarge ? LARGE_GEAR_Y : GEAR_Y;
}
@Override
public float getParticleTargetRadius() {
return isLarge ? 1.125f : .65f;
}
@Override
public float getParticleInitialRadius() {
return isLarge ? 1f : .75f;
}
// IRotate
@Override

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;
}
@Override
public float getParticleTargetRadius() {
return .25f;
}
@Override
public float getParticleInitialRadius() {
return 0f;
}
// IRotate:
@Override

View file

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

View file

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

View file

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

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": "Schematic",
"item.create.belt_connector": "Mechanical Belt",
"item.create.goggles": "Engineer's Goggles",
"item.create.filter": "Filter",
"item.create.rose_quartz": "Rose Quartz",
"item.create.refined_rose_quartz": "Refined Rose Quartz",
@ -78,8 +79,8 @@
"block.create.mechanical_piston_head": "Mechanical Piston Head",
"block.create.piston_pole": "Piston Extension Pole",
"block.create.mechanical_bearing": "Mechanical Bearing",
"block.create.translation_chassis": "Translation Chassis",
"block.create.rotation_chassis": "Rotation Chassis",
"block.create.translation_chassis": "Linear Chassis",
"block.create.rotation_chassis": "Radial Chassis",
"block.create.contact": "Redstone Contact",
"block.create.redstone_bridge": "Redstone Link",
@ -107,6 +108,8 @@
"block.create.diorite_bricks": "Diorite Bricks",
"block.create.granite_bricks": "Granite Bricks",
"block.create.volcanic_rock": "Basalt",
"block.create.gabbro": "Gabbro",
"block.create.gabbro_stairs": "Gabbro Stairs",
"block.create.gabbro_slab": "Gabbro Slab",
@ -515,10 +518,10 @@
"item.create.belt_connector.tooltip.control2": "R-Click while Sneaking",
"item.create.belt_connector.tooltip.action2": "_Resets_ the first selected position for the Belt",
"block.create.belt_support.tooltip": "BELT SUPPORT",
"block.create.belt_support.tooltip.summary": "A _purely_ _decorational_ block suitable for mounting _Mechanical_ _Belts_ to the Ground.",
"block.create.belt_support.tooltip.condition1": "When placed below a Belt",
"block.create.belt_support.tooltip.behaviour1": "Supports the top of the Belt, hiding the bottom layer.",
"item.create.goggles.tooltip": "GOGGLES",
"item.create.goggles.tooltip.summary": "A pair of glasses to augment your vision with useful _kinetic_ _information._",
"item.create.goggles.tooltip.condition1": "When worn",
"item.create.goggles.tooltip.behaviour1": "Shows _colored_ _indicators_ corresponding to the _Speed_ _Level_ of a placed kinetic component.",
"block.create.motor.tooltip": "MOTOR",
"block.create.motor.tooltip.summary": "A configurable source of _Rotational_ _Force_",
@ -549,6 +552,13 @@
"block.create.mechanical_press.tooltip.behaviour1": "_Starts_ to compress items dropped below it.",
"block.create.mechanical_press.tooltip.condition2": "When Above a Mechanical Belt",
"block.create.mechanical_press.tooltip.behaviour2": "_Automatically_ compresses bypassing items on the Belt.",
"block.create.mechanical_mixer.tooltip": "MECHANICAL MIXER",
"block.create.mechanical_mixer.tooltip.summary": "A kinetic whisk for applying any shapeless crafting recipes to items beneath it. Requires constant _Rotational_ _Force_ and a _Basin_ placed below (with a gap inbetween).",
"block.create.mechanical_mixer.tooltip.condition1": "When above Basin",
"block.create.mechanical_mixer.tooltip.behaviour1": "Starts to mix items in the basin whenever all necessary ingredients are present.",
"block.create.mechanical_mixer.tooltip.condition2": "When used with Wrench",
"block.create.mechanical_mixer.tooltip.behaviour2": "_Configures_ the minimum amount of _different_ _ingredients_ required before the mixer should begin. Use this option to rule out unwanted recipes with similar but less ingredients.",
"block.create.mechanical_piston.tooltip": "MECHANICAL PISTON",
"block.create.mechanical_piston.tooltip.summary": "A more advanced version of the _Piston,_ using _Rotational_ _Force_ to precisely move attached structures. _Piston_ _Extension_ _Poles_ at the rear define the _Range_ of this Device. Without extensions, the piston will not move. Use _Translation_ _Chassis_ to move more than a single line of blocks.",

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
}