mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-16 06:51:56 +01:00
merged mc1.15/dev into mc1.15-registrate
This commit is contained in:
commit
901cb00426
190 changed files with 6600 additions and 1702 deletions
|
@ -14,6 +14,7 @@ import com.simibubi.create.modules.IModule;
|
||||||
import com.simibubi.create.modules.contraptions.CasingBlock;
|
import com.simibubi.create.modules.contraptions.CasingBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.DrillBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.DrillBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.actors.PloughBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.clock.CuckooClockBlock;
|
import com.simibubi.create.modules.contraptions.components.clock.CuckooClockBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
|
||||||
|
@ -86,9 +87,6 @@ import com.simibubi.create.modules.palettes.HorizontalCTGlassBlock;
|
||||||
import com.simibubi.create.modules.palettes.LayeredCTBlock;
|
import com.simibubi.create.modules.palettes.LayeredCTBlock;
|
||||||
import com.simibubi.create.modules.palettes.ScoriaBlock;
|
import com.simibubi.create.modules.palettes.ScoriaBlock;
|
||||||
import com.simibubi.create.modules.palettes.VerticalCTGlassBlock;
|
import com.simibubi.create.modules.palettes.VerticalCTGlassBlock;
|
||||||
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
|
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
|
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
|
|
||||||
import com.tterrag.registrate.builders.BlockBuilder;
|
import com.tterrag.registrate.builders.BlockBuilder;
|
||||||
import com.tterrag.registrate.builders.ItemBuilder;
|
import com.tterrag.registrate.builders.ItemBuilder;
|
||||||
import com.tterrag.registrate.providers.ProviderType;
|
import com.tterrag.registrate.providers.ProviderType;
|
||||||
|
@ -172,9 +170,10 @@ public enum AllBlocks implements NonNullSupplier<Block> {
|
||||||
ROTATION_CHASSIS(RadialChassisBlock::new),
|
ROTATION_CHASSIS(RadialChassisBlock::new),
|
||||||
DRILL(DrillBlock::new),
|
DRILL(DrillBlock::new),
|
||||||
SAW(SawBlock::new),
|
SAW(SawBlock::new),
|
||||||
HARVESTER(HarvesterBlock::new),
|
|
||||||
DEPLOYER(DeployerBlock::new),
|
DEPLOYER(DeployerBlock::new),
|
||||||
PORTABLE_STORAGE_INTERFACE(PortableStorageInterfaceBlock::new),
|
PORTABLE_STORAGE_INTERFACE(PortableStorageInterfaceBlock::new),
|
||||||
|
HARVESTER(HarvesterBlock::new),
|
||||||
|
PLOUGH(PloughBlock::new),
|
||||||
ANALOG_LEVER(AnalogLeverBlock::new),
|
ANALOG_LEVER(AnalogLeverBlock::new),
|
||||||
|
|
||||||
ANDESITE_CASING(() -> new CasingBlock("andesite_casing")),
|
ANDESITE_CASING(() -> new CasingBlock("andesite_casing")),
|
||||||
|
|
|
@ -5,8 +5,6 @@ import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
|
import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
|
||||||
import com.tterrag.registrate.util.RegistryEntry;
|
import com.tterrag.registrate.util.RegistryEntry;
|
||||||
|
|
||||||
import net.minecraftforge.client.model.generators.ModelFile.UncheckedModelFile;
|
|
||||||
|
|
||||||
public class AllBlocksNew {
|
public class AllBlocksNew {
|
||||||
|
|
||||||
private static final CreateRegistrate REGISTRATE = Create.registrate();
|
private static final CreateRegistrate REGISTRATE = Create.registrate();
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.util.function.Function;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueRenderer;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityClassification;
|
import net.minecraft.entity.EntityClassification;
|
||||||
|
@ -23,6 +25,8 @@ public enum AllEntities {
|
||||||
ContraptionEntity::build),
|
ContraptionEntity::build),
|
||||||
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
||||||
false, ContraptionEntity::build),
|
false, ContraptionEntity::build),
|
||||||
|
SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 30, Integer.MAX_VALUE, false, SuperGlueEntity::build),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private IFactory<?> factory;
|
private IFactory<?> factory;
|
||||||
|
@ -63,8 +67,8 @@ public enum AllEntities {
|
||||||
@SuppressWarnings("unchecked") // TODO 1.15 this generic stuff is incompatible with the enum system - need strong types
|
@SuppressWarnings("unchecked") // TODO 1.15 this generic stuff is incompatible with the enum system - need strong types
|
||||||
@OnlyIn(value = Dist.CLIENT)
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
public static void registerRenderers() {
|
public static void registerRenderers() {
|
||||||
// RenderingRegistry.registerEntityRenderingHandler(CardboardBoxEntity.class, CardboardBoxEntityRenderer::new);
|
|
||||||
RenderingRegistry.registerEntityRenderingHandler((EntityType<ContraptionEntity>) CONTRAPTION.type, ContraptionEntityRenderer::new);
|
RenderingRegistry.registerEntityRenderingHandler((EntityType<ContraptionEntity>) CONTRAPTION.type, ContraptionEntityRenderer::new);
|
||||||
|
RenderingRegistry.registerEntityRenderingHandler((EntityType<SuperGlueEntity>) SUPER_GLUE.type, SuperGlueRenderer::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ import com.simibubi.create.foundation.utility.data.ITaggable;
|
||||||
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.GogglesItem;
|
||||||
import com.simibubi.create.modules.contraptions.WrenchItem;
|
import com.simibubi.create.modules.contraptions.WrenchItem;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueItem;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MinecartContraptionItem;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
|
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
|
||||||
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
|
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
|
||||||
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
||||||
|
@ -38,6 +40,7 @@ import com.simibubi.create.modules.schematics.item.SchematicItem;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.color.ItemColors;
|
import net.minecraft.client.renderer.color.ItemColors;
|
||||||
import net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer;
|
import net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer;
|
||||||
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity.Type;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.Item.Properties;
|
import net.minecraft.item.Item.Properties;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -75,8 +78,8 @@ public enum AllItems {
|
||||||
ZINC_INGOT((TaggedItem) new TaggedItem().withForgeTags("ingots/zinc")),
|
ZINC_INGOT((TaggedItem) new TaggedItem().withForgeTags("ingots/zinc")),
|
||||||
BRASS_INGOT((TaggedItem) new TaggedItem().withForgeTags("ingots/brass")),
|
BRASS_INGOT((TaggedItem) new TaggedItem().withForgeTags("ingots/brass")),
|
||||||
|
|
||||||
SAND_PAPER(SandPaperItem::new),
|
FLOUR,
|
||||||
RED_SAND_PAPER(SandPaperItem::new),
|
DOUGH,
|
||||||
OBSIDIAN_DUST,
|
OBSIDIAN_DUST,
|
||||||
ROSE_QUARTZ,
|
ROSE_QUARTZ,
|
||||||
POLISHED_ROSE_QUARTZ,
|
POLISHED_ROSE_QUARTZ,
|
||||||
|
@ -86,23 +89,20 @@ public enum AllItems {
|
||||||
ELECTRON_TUBE,
|
ELECTRON_TUBE,
|
||||||
INTEGRATED_CIRCUIT,
|
INTEGRATED_CIRCUIT,
|
||||||
|
|
||||||
__SCHEMATICS__(module()),
|
|
||||||
EMPTY_BLUEPRINT(Item::new, stackSize(1)),
|
|
||||||
BLUEPRINT_AND_QUILL(SchematicAndQuillItem::new, stackSize(1)),
|
|
||||||
BLUEPRINT(SchematicItem::new),
|
|
||||||
|
|
||||||
__CONTRAPTIONS__(module()),
|
__CONTRAPTIONS__(module()),
|
||||||
BELT_CONNECTOR(BeltConnectorItem::new),
|
BELT_CONNECTOR(BeltConnectorItem::new),
|
||||||
VERTICAL_GEARBOX(VerticalGearboxItem::new),
|
VERTICAL_GEARBOX(VerticalGearboxItem::new),
|
||||||
FLOUR,
|
|
||||||
DOUGH,
|
|
||||||
PROPELLER,
|
PROPELLER,
|
||||||
WHISK,
|
WHISK,
|
||||||
BRASS_HAND,
|
BRASS_HAND,
|
||||||
SLOT_COVER,
|
SLOT_COVER,
|
||||||
ZINC_HANDLE,
|
SUPER_GLUE(SuperGlueItem::new),
|
||||||
|
SAND_PAPER(SandPaperItem::new),
|
||||||
|
RED_SAND_PAPER(SandPaperItem::new),
|
||||||
WRENCH(WrenchItem::new),
|
WRENCH(WrenchItem::new),
|
||||||
GOGGLES(GogglesItem::new),
|
GOGGLES(GogglesItem::new),
|
||||||
|
MINECART_CONTRAPTION(p -> new MinecartContraptionItem(Type.RIDEABLE, p)),
|
||||||
|
FURNACE_MINECART_CONTRAPTION(p -> new MinecartContraptionItem(Type.FURNACE, p)),
|
||||||
|
|
||||||
__LOGISTICS__(module()),
|
__LOGISTICS__(module()),
|
||||||
FILTER(FilterItem::new),
|
FILTER(FilterItem::new),
|
||||||
|
@ -114,6 +114,7 @@ public enum AllItems {
|
||||||
TERRAIN_ZAPPER(TerrainzapperItem::new),
|
TERRAIN_ZAPPER(TerrainzapperItem::new),
|
||||||
DEFORESTER(DeforesterItem::new),
|
DEFORESTER(DeforesterItem::new),
|
||||||
SYMMETRY_WAND(SymmetryWandItem::new),
|
SYMMETRY_WAND(SymmetryWandItem::new),
|
||||||
|
ZINC_HANDLE,
|
||||||
|
|
||||||
BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)),
|
BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)),
|
||||||
BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)),
|
BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)),
|
||||||
|
@ -129,6 +130,11 @@ public enum AllItems {
|
||||||
SHADOW_STEEL_MATTOCK(p -> new ShadowSteelToolItem(2.5F, -1.5F, p, SHOVEL, AXE, HOE)),
|
SHADOW_STEEL_MATTOCK(p -> new ShadowSteelToolItem(2.5F, -1.5F, p, SHOVEL, AXE, HOE)),
|
||||||
SHADOW_STEEL_SWORD(p -> new SwordItem(AllToolTiers.SHADOW_STEEL, 3, -2.0F, p)),
|
SHADOW_STEEL_SWORD(p -> new SwordItem(AllToolTiers.SHADOW_STEEL, 3, -2.0F, p)),
|
||||||
|
|
||||||
|
__SCHEMATICS__(module()),
|
||||||
|
EMPTY_BLUEPRINT(Item::new, stackSize(1)),
|
||||||
|
BLUEPRINT_AND_QUILL(SchematicAndQuillItem::new, stackSize(1)),
|
||||||
|
BLUEPRINT(SchematicItem::new),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private static class CategoryTracker {
|
private static class CategoryTracker {
|
||||||
|
@ -197,7 +203,8 @@ public enum AllItems {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entry.item = entry.taggedItem.getItemSupplier().apply(new Properties());
|
entry.item = entry.taggedItem.getItemSupplier().apply(new Properties());
|
||||||
entry.item = entry.taggedItem.getItemSupplier().apply(entry.specialProperties.apply(defaultProperties(entry)));
|
entry.item =
|
||||||
|
entry.taggedItem.getItemSupplier().apply(entry.specialProperties.apply(defaultProperties(entry)));
|
||||||
entry.item.setRegistryName(Create.ID, Lang.asId(entry.name()));
|
entry.item.setRegistryName(Create.ID, Lang.asId(entry.name()));
|
||||||
registry.register(entry.item);
|
registry.register(entry.item);
|
||||||
}
|
}
|
||||||
|
@ -224,11 +231,11 @@ public enum AllItems {
|
||||||
private Set<ResourceLocation> tagSetItem = new HashSet<>();
|
private Set<ResourceLocation> tagSetItem = new HashSet<>();
|
||||||
private Function<Properties, Item> itemSupplier;
|
private Function<Properties, Item> itemSupplier;
|
||||||
|
|
||||||
public TaggedItem(){
|
public TaggedItem() {
|
||||||
this(Item::new);
|
this(Item::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaggedItem(Function<Properties, Item> itemSupplierIn){
|
public TaggedItem(Function<Properties, Item> itemSupplierIn) {
|
||||||
this.itemSupplier = itemSupplierIn;
|
this.itemSupplier = itemSupplierIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.CancelPlayerFallPacket;
|
import com.simibubi.create.modules.contraptions.components.contraptions.CancelPlayerFallPacket;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.GlueEffectPacket;
|
||||||
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
||||||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
||||||
import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket;
|
import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket;
|
||||||
|
@ -51,6 +52,7 @@ public enum AllPackets {
|
||||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
||||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
||||||
TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new),
|
TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new),
|
||||||
|
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
@EventBusSubscriber(value = Dist.CLIENT)
|
@EventBusSubscriber(value = Dist.CLIENT)
|
||||||
public enum AllSpecialTextures {
|
public enum AllSpecialTextures {
|
||||||
|
|
||||||
|
BLANK("blank.png"),
|
||||||
|
CHECKERED("checkerboard.png"),
|
||||||
|
HIGHLIGHT_CHECKERED("highlighted_checkerboard.png"),
|
||||||
SELECTION("selection.png"),
|
SELECTION("selection.png"),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
|
@ -16,6 +16,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.bearing.
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyRenderer;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyRenderer;
|
||||||
|
@ -148,6 +149,7 @@ public enum AllTileEntities {
|
||||||
SPEED_GAUGE(SpeedGaugeTileEntity::new, AllBlocks.SPEED_GAUGE),
|
SPEED_GAUGE(SpeedGaugeTileEntity::new, AllBlocks.SPEED_GAUGE),
|
||||||
STRESS_GAUGE(StressGaugeTileEntity::new, AllBlocks.STRESS_GAUGE),
|
STRESS_GAUGE(StressGaugeTileEntity::new, AllBlocks.STRESS_GAUGE),
|
||||||
ANALOG_LEVER(AnalogLeverTileEntity::new, AllBlocks.ANALOG_LEVER),
|
ANALOG_LEVER(AnalogLeverTileEntity::new, AllBlocks.ANALOG_LEVER),
|
||||||
|
CART_ASSEMBLER(CartAssemblerTileEntity::new, AllBlocks.CART_ASSEMBLER),
|
||||||
|
|
||||||
// Logistics
|
// Logistics
|
||||||
REDSTONE_BRIDGE(RedstoneLinkTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
REDSTONE_BRIDGE(RedstoneLinkTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
||||||
|
|
|
@ -80,8 +80,6 @@ public class ClientEvents {
|
||||||
|
|
||||||
IRenderTypeBuffer.Impl buffer = Minecraft.getInstance().getBufferBuilders().getEntityVertexConsumers();
|
IRenderTypeBuffer.Impl buffer = Minecraft.getInstance().getBufferBuilders().getEntityVertexConsumers();
|
||||||
CreateClient.schematicHandler.render(ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV);
|
CreateClient.schematicHandler.render(ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV);
|
||||||
CreateClient.schematicAndQuillHandler.render(ms, buffer);
|
|
||||||
CreateClient.schematicHologram.render(ms, buffer);
|
|
||||||
KineticDebugger.renderSourceOutline(ms, buffer);
|
KineticDebugger.renderSourceOutline(ms, buffer);
|
||||||
ChassisRangeDisplay.renderOutlines(event.getPartialTicks(), ms, buffer);
|
ChassisRangeDisplay.renderOutlines(event.getPartialTicks(), ms, buffer);
|
||||||
TerrainZapperRenderHandler.render(ms, buffer);
|
TerrainZapperRenderHandler.render(ms, buffer);
|
||||||
|
|
|
@ -16,7 +16,6 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Contrapt
|
||||||
import com.simibubi.create.modules.schematics.ClientSchematicLoader;
|
import com.simibubi.create.modules.schematics.ClientSchematicLoader;
|
||||||
import com.simibubi.create.modules.schematics.client.SchematicAndQuillHandler;
|
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 net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -41,10 +40,8 @@ public class CreateClient {
|
||||||
|
|
||||||
public static ClientSchematicLoader schematicSender;
|
public static ClientSchematicLoader schematicSender;
|
||||||
public static SchematicHandler schematicHandler;
|
public static SchematicHandler schematicHandler;
|
||||||
public static SchematicHologram schematicHologram;
|
|
||||||
public static SchematicAndQuillHandler schematicAndQuillHandler;
|
public static SchematicAndQuillHandler schematicAndQuillHandler;
|
||||||
public static SuperByteBufferCache bufferCache;
|
public static SuperByteBufferCache bufferCache;
|
||||||
public static int renderTicks;
|
|
||||||
|
|
||||||
public static void addListeners(IEventBus modEventBus) {
|
public static void addListeners(IEventBus modEventBus) {
|
||||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
@ -59,7 +56,6 @@ public class CreateClient {
|
||||||
public static void clientInit(FMLClientSetupEvent event) {
|
public static void clientInit(FMLClientSetupEvent event) {
|
||||||
schematicSender = new ClientSchematicLoader();
|
schematicSender = new ClientSchematicLoader();
|
||||||
schematicHandler = new SchematicHandler();
|
schematicHandler = new SchematicHandler();
|
||||||
schematicHologram = new SchematicHologram();
|
|
||||||
schematicAndQuillHandler = new SchematicAndQuillHandler();
|
schematicAndQuillHandler = new SchematicAndQuillHandler();
|
||||||
|
|
||||||
bufferCache = new SuperByteBufferCache();
|
bufferCache = new SuperByteBufferCache();
|
||||||
|
@ -82,7 +78,6 @@ public class CreateClient {
|
||||||
schematicSender.tick();
|
schematicSender.tick();
|
||||||
schematicAndQuillHandler.tick();
|
schematicAndQuillHandler.tick();
|
||||||
schematicHandler.tick();
|
schematicHandler.tick();
|
||||||
schematicHologram.tick();
|
|
||||||
ChassisRangeDisplay.clientTick();
|
ChassisRangeDisplay.clientTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ public enum ScreenResources {
|
||||||
|
|
||||||
// JEI
|
// JEI
|
||||||
JEI_SLOT("jei/widgets.png", 18, 18),
|
JEI_SLOT("jei/widgets.png", 18, 18),
|
||||||
|
JEI_CHANCE_SLOT("jei/widgets.png", 20, 156, 18, 18),
|
||||||
JEI_CATALYST_SLOT("jei/widgets.png", 0, 156, 18, 18),
|
JEI_CATALYST_SLOT("jei/widgets.png", 0, 156, 18, 18),
|
||||||
JEI_ARROW("jei/widgets.png", 19, 10, 42, 10),
|
JEI_ARROW("jei/widgets.png", 19, 10, 42, 10),
|
||||||
JEI_LONG_ARROW("jei/widgets.png", 19, 0, 71, 10),
|
JEI_LONG_ARROW("jei/widgets.png", 19, 0, 71, 10),
|
||||||
|
@ -132,6 +133,9 @@ public enum ScreenResources {
|
||||||
I_MOVE_PLACE(9, 1),
|
I_MOVE_PLACE(9, 1),
|
||||||
I_MOVE_PLACE_RETURNED(10, 1),
|
I_MOVE_PLACE_RETURNED(10, 1),
|
||||||
I_MOVE_NEVER_PLACE(11, 1),
|
I_MOVE_NEVER_PLACE(11, 1),
|
||||||
|
I_CART_ROTATE(12, 1),
|
||||||
|
I_CART_ROTATE_PAUSED(13, 1),
|
||||||
|
I_CART_ROTATE_LOCKED(14, 1),
|
||||||
|
|
||||||
I_DONT_REPLACE(0, 2),
|
I_DONT_REPLACE(0, 2),
|
||||||
I_REPLACE_SOLID(1, 2),
|
I_REPLACE_SOLID(1, 2),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.compat.jei;
|
package com.simibubi.create.compat.jei;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -28,13 +27,11 @@ import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCraftingRecipe;
|
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCraftingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe;
|
import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.components.press.MechanicalPressTileEntity;
|
import com.simibubi.create.modules.contraptions.components.press.MechanicalPressTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
|
||||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicannonScreen;
|
import com.simibubi.create.modules.schematics.block.SchematicannonScreen;
|
||||||
|
|
||||||
import mezz.jei.api.IModPlugin;
|
import mezz.jei.api.IModPlugin;
|
||||||
import mezz.jei.api.JeiPlugin;
|
import mezz.jei.api.JeiPlugin;
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
|
||||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||||
|
@ -226,28 +223,4 @@ public class CreateJEI implements IModPlugin {
|
||||||
return byType;
|
return byType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List<ProcessingOutput> results) {
|
|
||||||
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
|
|
||||||
if (input)
|
|
||||||
return;
|
|
||||||
ProcessingOutput output = results.get(slotIndex - 1);
|
|
||||||
if (output.getChance() != 1)
|
|
||||||
tooltip.add(1, TextFormatting.GOLD
|
|
||||||
+ Lang.translate("recipe.processing.chance", (int) (output.getChance() * 100)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addCatalystTooltip(IGuiItemStackGroup itemStacks, Map<Integer, Float> catalystIndices) {
|
|
||||||
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
|
|
||||||
if (!input)
|
|
||||||
return;
|
|
||||||
if (!catalystIndices.containsKey(slotIndex))
|
|
||||||
return;
|
|
||||||
Float chance = catalystIndices.get(slotIndex);
|
|
||||||
tooltip.add(1, TextFormatting.YELLOW + Lang.translate("recipe.processing.catalyst"));
|
|
||||||
tooltip.add(2, TextFormatting.GOLD
|
|
||||||
+ Lang.translate("recipe.processing.chanceToReturn", (int) (chance.floatValue() * 100)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,38 +2,18 @@ package com.simibubi.create.compat.jei.category;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
|
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.FlowingFluidBlock;
|
import net.minecraft.block.FlowingFluidBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.item.crafting.AbstractCookingRecipe;
|
import net.minecraft.item.crafting.AbstractCookingRecipe;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class BlastingViaFanCategory extends ProcessingViaFanCategory<AbstractCookingRecipe> {
|
public class BlastingViaFanCategory extends ProcessingViaFanCategory<AbstractCookingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "blasting_via_fan");
|
|
||||||
private IDrawable icon;
|
|
||||||
|
|
||||||
public BlastingViaFanCategory() {
|
public BlastingViaFanCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()),
|
super("blasting_via_fan", doubleItemIcon(AllItems.PROPELLER.get(), Items.LAVA_BUCKET));
|
||||||
() -> new ItemStack(Items.LAVA_BUCKET));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,11 +21,6 @@ public class BlastingViaFanCategory extends ProcessingViaFanCategory<AbstractCoo
|
||||||
return AbstractCookingRecipe.class;
|
return AbstractCookingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.blastingViaFan");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAttachedBlock() {
|
public void renderAttachedBlock() {
|
||||||
BlockState state = Blocks.LAVA.getDefaultState().with(FlowingFluidBlock.LEVEL, 8);
|
BlockState state = Blocks.LAVA.getDefaultState().with(FlowingFluidBlock.LEVEL, 8);
|
||||||
|
|
|
@ -5,21 +5,15 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.BlockCuttingCategory.CondensedBlockCuttingRecipe;
|
import com.simibubi.create.compat.jei.category.BlockCuttingCategory.CondensedBlockCuttingRecipe;
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
@ -27,27 +21,12 @@ import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.item.crafting.StonecuttingRecipe;
|
import net.minecraft.item.crafting.StonecuttingRecipe;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class BlockCuttingCategory implements IRecipeCategory<CondensedBlockCuttingRecipe> {
|
public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCuttingRecipe> {
|
||||||
|
|
||||||
private AnimatedSaw saw;
|
private AnimatedSaw saw = new AnimatedSaw();
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "block_cutting");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public BlockCuttingCategory() {
|
public BlockCuttingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.SAW.get()),
|
super("block_cutting", doubleItemIcon(AllBlocks.SAW.get(), Items.STONE_BRICK_STAIRS), emptyBackground(177, 70));
|
||||||
() -> new ItemStack(Items.STONE_BRICK_STAIRS));
|
|
||||||
saw = new AnimatedSaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,16 +34,6 @@ public class BlockCuttingCategory implements IRecipeCategory<CondensedBlockCutti
|
||||||
return CondensedBlockCuttingRecipe.class;
|
return CondensedBlockCuttingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.block_cutting");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(CondensedBlockCuttingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(CondensedBlockCuttingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
|
|
@ -9,8 +9,6 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.ScreenResourceWrapper;
|
import com.simibubi.create.compat.jei.ScreenResourceWrapper;
|
||||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
@ -18,38 +16,21 @@ import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperUpg
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
import net.minecraft.client.util.ITooltipFlag;
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.item.crafting.ShapedRecipe;
|
import net.minecraft.item.crafting.ShapedRecipe;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
public class BlockzapperUpgradeCategory implements IRecipeCategory<BlockzapperUpgradeRecipe> {
|
public class BlockzapperUpgradeCategory extends CreateRecipeCategory<BlockzapperUpgradeRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "blockzapper_upgrade");
|
|
||||||
private IDrawable icon;
|
|
||||||
|
|
||||||
public BlockzapperUpgradeCategory() {
|
public BlockzapperUpgradeCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PLACEMENT_HANDGUN.get()),
|
super("blockzapper_upgrade", itemIcon(AllItems.PLACEMENT_HANDGUN.get()),
|
||||||
() -> ItemStack.EMPTY); // replace with uparrow when available
|
new ScreenResourceWrapper(BLOCKZAPPER_UPGRADE_RECIPE));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,16 +38,6 @@ public class BlockzapperUpgradeCategory implements IRecipeCategory<BlockzapperUp
|
||||||
return BlockzapperUpgradeRecipe.class;
|
return BlockzapperUpgradeRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.blockzapperUpgrade");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return new ScreenResourceWrapper(BLOCKZAPPER_UPGRADE_RECIPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(BlockzapperUpgradeRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(BlockzapperUpgradeRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -90,8 +61,6 @@ public class BlockzapperUpgradeCategory implements IRecipeCategory<BlockzapperUp
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// itemStacks.init(9, false, BLOCKZAPPER_UPGRADE_RECIPE.width / 2 - 9, BLOCKZAPPER_UPGRADE_RECIPE.height - 18 - 10);
|
|
||||||
// itemStacks.set(9, recipe.getRecipeOutput());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,11 +79,11 @@ public class BlockzapperUpgradeCategory implements IRecipeCategory<BlockzapperUp
|
||||||
@Override
|
@Override
|
||||||
public void draw(BlockzapperUpgradeRecipe recipe, double mouseX, double mouseY) {
|
public void draw(BlockzapperUpgradeRecipe recipe, double mouseX, double mouseY) {
|
||||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||||
String componentName = Lang
|
String componentName =
|
||||||
.translate("blockzapper.component." + Lang.asId(recipe.getUpgradedComponent().name()));
|
Lang.translate("blockzapper.component." + Lang.asId(recipe.getUpgradedComponent().name()));
|
||||||
String text = "+ " + recipe.getTier().color + componentName;
|
String text = "+ " + recipe.getTier().color + componentName;
|
||||||
font.drawStringWithShadow(text,
|
font.drawStringWithShadow(text, (BLOCKZAPPER_UPGRADE_RECIPE.width - font.getStringWidth(text)) / 2, 57,
|
||||||
(BLOCKZAPPER_UPGRADE_RECIPE.width - font.getStringWidth(text)) / 2, 57, 0x8B8B8B);
|
0x8B8B8B);
|
||||||
|
|
||||||
RenderSystem.pushMatrix();
|
RenderSystem.pushMatrix();
|
||||||
RenderSystem.translated(126, 0, 0);
|
RenderSystem.translated(126, 0, 0);
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.simibubi.create.compat.jei.category;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.ScreenResources;
|
||||||
|
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
||||||
|
import com.simibubi.create.compat.jei.EmptyBackground;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe;
|
||||||
|
|
||||||
|
import mezz.jei.api.gui.drawable.IDrawable;
|
||||||
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
|
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.util.IItemProvider;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
|
||||||
|
public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRecipeCategory<T> {
|
||||||
|
|
||||||
|
private ResourceLocation uid;
|
||||||
|
private String name;
|
||||||
|
private IDrawable icon;
|
||||||
|
private IDrawable background;
|
||||||
|
|
||||||
|
public CreateRecipeCategory(String id, IDrawable icon, IDrawable background) {
|
||||||
|
uid = new ResourceLocation(Create.ID, id);
|
||||||
|
name = id;
|
||||||
|
this.background = background;
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDrawable getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getUid() {
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return Lang.translate("recipe." + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IDrawable getBackground() {
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static ScreenResources getRenderedSlot(IRecipe<?> recipe, int index) {
|
||||||
|
ScreenResources jeiSlot = ScreenResources.JEI_SLOT;
|
||||||
|
if (!(recipe instanceof ProcessingRecipe))
|
||||||
|
return jeiSlot;
|
||||||
|
ProcessingRecipe<?> processingRecipe = (ProcessingRecipe<?>) recipe;
|
||||||
|
List<ProcessingOutput> rollableResults = processingRecipe.getRollableResults();
|
||||||
|
if (rollableResults.size() <= index)
|
||||||
|
return jeiSlot;
|
||||||
|
if (processingRecipe.getRollableResults().get(index).getChance() == 1)
|
||||||
|
return jeiSlot;
|
||||||
|
return ScreenResources.JEI_CHANCE_SLOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static IDrawable emptyBackground(int width, int height) {
|
||||||
|
return new EmptyBackground(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static IDrawable doubleItemIcon(IItemProvider item1, IItemProvider item2) {
|
||||||
|
return new DoubleItemIcon(() -> new ItemStack(item1), () -> new ItemStack(item2));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static IDrawable itemIcon(IItemProvider item) {
|
||||||
|
return new DoubleItemIcon(() -> new ItemStack(item), () -> ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List<ProcessingOutput> results) {
|
||||||
|
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
|
||||||
|
if (input)
|
||||||
|
return;
|
||||||
|
ProcessingOutput output = results.get(slotIndex - 1);
|
||||||
|
if (output.getChance() != 1)
|
||||||
|
tooltip.add(1, TextFormatting.GOLD
|
||||||
|
+ Lang.translate("recipe.processing.chance", (int) (output.getChance() * 100)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void addCatalystTooltip(IGuiItemStackGroup itemStacks, Map<Integer, Float> catalystIndices) {
|
||||||
|
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
|
||||||
|
if (!input)
|
||||||
|
return;
|
||||||
|
if (!catalystIndices.containsKey(slotIndex))
|
||||||
|
return;
|
||||||
|
Float chance = catalystIndices.get(slotIndex);
|
||||||
|
tooltip.add(1, TextFormatting.YELLOW + Lang.translate("recipe.processing.catalyst"));
|
||||||
|
tooltip.add(2, TextFormatting.GOLD
|
||||||
|
+ Lang.translate("recipe.processing.chanceToReturn", (int) (chance.floatValue() * 100)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,45 +5,23 @@ import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedCrushingWheels;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedCrushingWheels;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe;
|
import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class CrushingCategory implements IRecipeCategory<AbstractCrushingRecipe> {
|
public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "crushing");
|
|
||||||
private AnimatedCrushingWheels crushingWheels = new AnimatedCrushingWheels();
|
private AnimatedCrushingWheels crushingWheels = new AnimatedCrushingWheels();
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 100);
|
|
||||||
|
|
||||||
public CrushingCategory() {
|
public CrushingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.CRUSHING_WHEEL.get()),
|
super("crushing", doubleItemIcon(AllBlocks.CRUSHING_WHEEL.get(), AllItems.CRUSHED_GOLD.get()),
|
||||||
() -> new ItemStack(AllItems.CRUSHED_GOLD.get()));
|
emptyBackground(177, 100));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,16 +29,6 @@ public class CrushingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
return AbstractCrushingRecipe.class;
|
return AbstractCrushingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.crushing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -81,7 +49,7 @@ public class CrushingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,7 +61,7 @@ public class CrushingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
int size = results.size();
|
int size = results.size();
|
||||||
int offset = -size * 19 / 2;
|
int offset = -size * 19 / 2;
|
||||||
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++)
|
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++)
|
||||||
ScreenResources.JEI_SLOT.draw(getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78);
|
getRenderedSlot(recipe, outputIndex).draw(getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78);
|
||||||
|
|
||||||
crushingWheels.draw(92, 49);
|
crushingWheels.draw(92, 49);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,65 +3,39 @@ package com.simibubi.create.compat.jei.category;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.item.crafting.ShapedRecipe;
|
import net.minecraft.item.crafting.ShapedRecipe;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class MechanicalCraftingCategory implements IRecipeCategory<ShapedRecipe> {
|
public class MechanicalCraftingCategory extends CreateRecipeCategory<ShapedRecipe> {
|
||||||
|
|
||||||
private AnimatedCrafter crafter;
|
private AnimatedCrafter crafter;
|
||||||
private ResourceLocation id;
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background;
|
|
||||||
private boolean large;
|
private boolean large;
|
||||||
|
|
||||||
public MechanicalCraftingCategory(boolean large) {
|
public MechanicalCraftingCategory(boolean large) {
|
||||||
|
super("mechanical_crafting" + (large ? "_large" : ""), itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()),
|
||||||
|
emptyBackground(large ? 177 : 177, large ? 235 : 81));
|
||||||
this.large = large;
|
this.large = large;
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), () -> ItemStack.EMPTY);
|
|
||||||
crafter = new AnimatedCrafter(large);
|
crafter = new AnimatedCrafter(large);
|
||||||
id = new ResourceLocation(Create.ID, "mechanical_crafting" + (large ? "_large" : ""));
|
|
||||||
background = new EmptyBackground(large ? 177 : 177, large ? 235 : 81);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSmall(ShapedRecipe recipe) {
|
public static boolean isSmall(ShapedRecipe recipe) {
|
||||||
return Math.max((recipe).getWidth(), (recipe).getHeight()) <= 4;
|
return Math.max((recipe).getWidth(), (recipe).getHeight()) <= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return Lang.translate("recipe.mechanical_crafting");
|
return Lang.translate("recipe.mechanical_crafting");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(ShapedRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(ShapedRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
|
|
@ -5,45 +5,22 @@ import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedMillstone;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedMillstone;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe;
|
import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class MillingCategory implements IRecipeCategory<AbstractCrushingRecipe> {
|
public class MillingCategory extends CreateRecipeCategory<AbstractCrushingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "milling");
|
|
||||||
private AnimatedMillstone millstone = new AnimatedMillstone();
|
private AnimatedMillstone millstone = new AnimatedMillstone();
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 53);
|
|
||||||
|
|
||||||
public MillingCategory() {
|
public MillingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MILLSTONE.get()),
|
super("milling", doubleItemIcon(AllBlocks.MILLSTONE.get(), AllItems.FLOUR.get()), emptyBackground(177, 53));
|
||||||
() -> new ItemStack(AllItems.FLOUR.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,16 +28,6 @@ public class MillingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
return AbstractCrushingRecipe.class;
|
return AbstractCrushingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.milling");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -83,7 +50,7 @@ public class MillingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,17 +62,19 @@ public class MillingCategory implements IRecipeCategory<AbstractCrushingRecipe>
|
||||||
ScreenResources.JEI_ARROW.draw(85, 32);
|
ScreenResources.JEI_ARROW.draw(85, 32);
|
||||||
ScreenResources.JEI_DOWN_ARROW.draw(43, 4);
|
ScreenResources.JEI_DOWN_ARROW.draw(43, 4);
|
||||||
|
|
||||||
if (size > 1) {
|
millstone.draw(57, 27);
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
int xOffset = i % 2 == 0 ? 0 : 19;
|
if (size == 1) {
|
||||||
int yOffset = (i / 2) * -19;
|
getRenderedSlot(recipe, 0).draw(139, 27);
|
||||||
ScreenResources.JEI_SLOT.draw(133 + xOffset, 27 + yOffset);
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ScreenResources.JEI_SLOT.draw(139, 27);
|
for (int i = 0; i < size; i++) {
|
||||||
|
int xOffset = i % 2 == 0 ? 0 : 19;
|
||||||
|
int yOffset = (i / 2) * -19;
|
||||||
|
getRenderedSlot(recipe, i).draw(133 + xOffset, 27 + yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
millstone.draw(57, 27);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,59 +10,32 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedMixer;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedMixer;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe;
|
import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class MixingCategory implements IRecipeCategory<MixingRecipe> {
|
public class MixingCategory extends CreateRecipeCategory<MixingRecipe> {
|
||||||
|
|
||||||
private AnimatedMixer mixer;
|
private AnimatedMixer mixer = new AnimatedMixer();
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "mixing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public MixingCategory() {
|
public MixingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_MIXER.get()),
|
super("mixing", doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), AllBlocks.BASIN.get()),
|
||||||
() -> new ItemStack(AllBlocks.BASIN.get()));
|
emptyBackground(177, 70));
|
||||||
mixer = new AnimatedMixer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IDrawable getIcon() {
|
public Class<? extends MixingRecipe> getRecipeClass() {
|
||||||
return icon;
|
return MixingRecipe.class;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.mixing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,13 +80,11 @@ public class MixingCategory implements IRecipeCategory<MixingRecipe> {
|
||||||
itemStacks.init(i, false, 141, 50);
|
itemStacks.init(i, false, 141, 50);
|
||||||
itemStacks.set(i, recipe.getRecipeOutput().getStack());
|
itemStacks.set(i, recipe.getRecipeOutput().getStack());
|
||||||
|
|
||||||
CreateJEI.addCatalystTooltip(itemStacks, catalystIndices);
|
addCatalystTooltip(itemStacks, catalystIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(MixingRecipe recipe, double mouseX, double mouseY) {
|
public void draw(MixingRecipe recipe, double mouseX, double mouseY) {
|
||||||
// this might actually be pretty bad with big ingredients. ^ its a draw method
|
|
||||||
|
|
||||||
List<Pair<Ingredient, MutableInt>> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients());
|
List<Pair<Ingredient, MutableInt>> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients());
|
||||||
|
|
||||||
int size = actualIngredients.size();
|
int size = actualIngredients.size();
|
||||||
|
@ -135,9 +106,4 @@ public class MixingCategory implements IRecipeCategory<MixingRecipe> {
|
||||||
mixer.draw(getBackground().getWidth() / 2 + 20, 8);
|
mixer.draw(getBackground().getWidth() / 2 + 20, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends MixingRecipe> getRecipeClass() {
|
|
||||||
return MixingRecipe.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,16 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.ConversionRecipe;
|
import com.simibubi.create.compat.jei.ConversionRecipe;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class MysteriousItemConversionCategory implements IRecipeCategory<ConversionRecipe> {
|
public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "mystery_conversion");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 50);
|
|
||||||
|
|
||||||
public static List<ConversionRecipe> getRecipes() {
|
public static List<ConversionRecipe> getRecipes() {
|
||||||
List<ConversionRecipe> recipes = new ArrayList<>();
|
List<ConversionRecipe> recipes = new ArrayList<>();
|
||||||
|
@ -37,17 +24,7 @@ public class MysteriousItemConversionCategory implements IRecipeCategory<Convers
|
||||||
}
|
}
|
||||||
|
|
||||||
public MysteriousItemConversionCategory() {
|
public MysteriousItemConversionCategory() {
|
||||||
icon = new DoubleItemIcon(() -> AllItems.CHROMATIC_COMPOUND.asStack(), () -> ItemStack.EMPTY);
|
super("mystery_conversion", itemIcon(AllItems.CHROMATIC_COMPOUND.get()), emptyBackground(177, 50));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,16 +32,6 @@ public class MysteriousItemConversionCategory implements IRecipeCategory<Convers
|
||||||
return ConversionRecipe.class;
|
return ConversionRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.mystery_conversion");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(ConversionRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(ConversionRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -75,13 +42,10 @@ public class MysteriousItemConversionCategory implements IRecipeCategory<Convers
|
||||||
public void setRecipe(IRecipeLayout recipeLayout, ConversionRecipe recipe, IIngredients ingredients) {
|
public void setRecipe(IRecipeLayout recipeLayout, ConversionRecipe recipe, IIngredients ingredients) {
|
||||||
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
|
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
|
||||||
List<ProcessingOutput> results = recipe.getRollableResults();
|
List<ProcessingOutput> results = recipe.getRollableResults();
|
||||||
|
|
||||||
itemStacks.init(0, true, 26, 16);
|
itemStacks.init(0, true, 26, 16);
|
||||||
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
|
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
|
||||||
itemStacks.init(1, false, 131, 16);
|
itemStacks.init(1, false, 131, 16);
|
||||||
itemStacks.set(1, results.get(0).getStack());
|
itemStacks.set(1, results.get(0).getStack());
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,47 +3,25 @@ package com.simibubi.create.compat.jei.category;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedPress;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedPress;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class PackingCategory implements IRecipeCategory<IRecipe<?>> {
|
public class PackingCategory extends CreateRecipeCategory<IRecipe<?>> {
|
||||||
|
|
||||||
private AnimatedPress press;
|
private AnimatedPress press = new AnimatedPress(true);
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "packing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public PackingCategory() {
|
public PackingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_PRESS.get()),
|
super("packing", doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllBlocks.BASIN.get()),
|
||||||
() -> new ItemStack(AllBlocks.BASIN.get()));
|
emptyBackground(177, 70));
|
||||||
press = new AnimatedPress(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,16 +29,6 @@ public class PackingCategory implements IRecipeCategory<IRecipe<?>> {
|
||||||
return ICraftingRecipe.class;
|
return ICraftingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.packing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(IRecipe<?> recipe, IIngredients ingredients) {
|
public void setIngredients(IRecipe<?> recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
|
|
@ -5,66 +5,35 @@ import java.util.List;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
import com.simibubi.create.modules.curiosities.tools.SandPaperPolishingRecipe;
|
import com.simibubi.create.modules.curiosities.tools.SandPaperPolishingRecipe;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ItemRenderer;
|
import net.minecraft.client.renderer.ItemRenderer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class PolishingCategory implements IRecipeCategory<SandPaperPolishingRecipe> {
|
public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "sandpaper_polishing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 55);
|
|
||||||
private ItemStack renderedSandpaper;
|
private ItemStack renderedSandpaper;
|
||||||
|
|
||||||
public PolishingCategory() {
|
public PolishingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> AllItems.SAND_PAPER.asStack(), () -> ItemStack.EMPTY);
|
super("sandpaper_polishing", itemIcon(AllItems.SAND_PAPER.get()), emptyBackground(177, 55));
|
||||||
renderedSandpaper = AllItems.SAND_PAPER.asStack();
|
renderedSandpaper = AllItems.SAND_PAPER.asStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends SandPaperPolishingRecipe> getRecipeClass() {
|
public Class<? extends SandPaperPolishingRecipe> getRecipeClass() {
|
||||||
return SandPaperPolishingRecipe.class;
|
return SandPaperPolishingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.sandpaper_polishing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(SandPaperPolishingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(SandPaperPolishingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -81,13 +50,13 @@ public class PolishingCategory implements IRecipeCategory<SandPaperPolishingReci
|
||||||
itemStacks.init(1, false, 131, 28);
|
itemStacks.init(1, false, 131, 28);
|
||||||
itemStacks.set(1, results.get(0).getStack());
|
itemStacks.set(1, results.get(0).getStack());
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(SandPaperPolishingRecipe recipe, double mouseX, double mouseY) {
|
public void draw(SandPaperPolishingRecipe recipe, double mouseX, double mouseY) {
|
||||||
ScreenResources.JEI_SLOT.draw(26, 28);
|
ScreenResources.JEI_SLOT.draw(26, 28);
|
||||||
ScreenResources.JEI_SLOT.draw(131, 28);
|
getRenderedSlot(recipe, 0).draw(131, 28);
|
||||||
ScreenResources.JEI_SHADOW.draw(61, 21);
|
ScreenResources.JEI_SHADOW.draw(61, 21);
|
||||||
ScreenResources.JEI_LONG_ARROW.draw(52, 32);
|
ScreenResources.JEI_LONG_ARROW.draw(52, 32);
|
||||||
|
|
||||||
|
|
|
@ -5,46 +5,23 @@ import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedPress;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedPress;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.press.PressingRecipe;
|
import com.simibubi.create.modules.contraptions.components.press.PressingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class PressingCategory implements IRecipeCategory<PressingRecipe> {
|
public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
|
||||||
|
|
||||||
private AnimatedPress press;
|
private AnimatedPress press = new AnimatedPress(false);
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "pressing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public PressingCategory() {
|
public PressingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_PRESS.get()),
|
super("pressing", doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllItems.IRON_SHEET.get()),
|
||||||
() -> new ItemStack(AllItems.IRON_SHEET.get()));
|
emptyBackground(177, 70));
|
||||||
press = new AnimatedPress(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,16 +29,6 @@ public class PressingCategory implements IRecipeCategory<PressingRecipe> {
|
||||||
return PressingRecipe.class;
|
return PressingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.pressing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(PressingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(PressingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -80,15 +47,15 @@ public class PressingCategory implements IRecipeCategory<PressingRecipe> {
|
||||||
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(PressingRecipe recipe, double mouseX, double mouseY) {
|
public void draw(PressingRecipe recipe, double mouseX, double mouseY) {
|
||||||
ScreenResources.JEI_SLOT.draw(26, 50);
|
ScreenResources.JEI_SLOT.draw(26, 50);
|
||||||
ScreenResources.JEI_SLOT.draw(131, 50);
|
getRenderedSlot(recipe, 0).draw(131, 50);
|
||||||
if (recipe.getRollableResults().size() > 1)
|
if (recipe.getRollableResults().size() > 1)
|
||||||
ScreenResources.JEI_SLOT.draw(131 + 19, 50);
|
getRenderedSlot(recipe, 1).draw(131 + 19, 50);
|
||||||
ScreenResources.JEI_SHADOW.draw(61, 41);
|
ScreenResources.JEI_SHADOW.draw(61, 41);
|
||||||
ScreenResources.JEI_LONG_ARROW.draw(52, 54);
|
ScreenResources.JEI_LONG_ARROW.draw(52, 54);
|
||||||
press.draw(getBackground().getWidth() / 2, 8);
|
press.draw(getBackground().getWidth() / 2, 8);
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
||||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||||
|
|
||||||
|
@ -15,20 +14,16 @@ import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
import mezz.jei.api.gui.drawable.IDrawable;
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
|
||||||
public abstract class ProcessingViaFanCategory<T extends IRecipe<?>> implements IRecipeCategory<T> {
|
public abstract class ProcessingViaFanCategory<T extends IRecipe<?>> extends CreateRecipeCategory<T> {
|
||||||
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
public ProcessingViaFanCategory(String name, IDrawable icon) {
|
||||||
|
super(name, icon, emptyBackground(177, 70));
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,46 +4,23 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.saw.CuttingRecipe;
|
import com.simibubi.create.modules.contraptions.components.saw.CuttingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class SawingCategory implements IRecipeCategory<CuttingRecipe> {
|
public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
|
||||||
|
|
||||||
private AnimatedSaw saw;
|
private AnimatedSaw saw = new AnimatedSaw();
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "sawing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public SawingCategory() {
|
public SawingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.SAW.get()), () -> new ItemStack(Items.OAK_LOG));
|
super("sawing", doubleItemIcon(AllBlocks.SAW.get(), Items.OAK_LOG), emptyBackground(177, 70));
|
||||||
saw = new AnimatedSaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,16 +28,6 @@ public class SawingCategory implements IRecipeCategory<CuttingRecipe> {
|
||||||
return CuttingRecipe.class;
|
return CuttingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.sawing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(CuttingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(CuttingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -82,7 +49,7 @@ public class SawingCategory implements IRecipeCategory<CuttingRecipe> {
|
||||||
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,7 +59,7 @@ public class SawingCategory implements IRecipeCategory<CuttingRecipe> {
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
int xOffset = i % 2 == 0 ? 0 : 19;
|
int xOffset = i % 2 == 0 ? 0 : 19;
|
||||||
int yOffset = (i / 2) * -19;
|
int yOffset = (i / 2) * -19;
|
||||||
ScreenResources.JEI_SLOT.draw(117 + xOffset, 47 + yOffset);
|
getRenderedSlot(recipe, i).draw(117 + xOffset, 47 + yOffset);
|
||||||
}
|
}
|
||||||
ScreenResources.JEI_DOWN_ARROW.draw(70, 6);
|
ScreenResources.JEI_DOWN_ARROW.draw(70, 6);
|
||||||
ScreenResources.JEI_SHADOW.draw(58, 55);
|
ScreenResources.JEI_SHADOW.draw(58, 55);
|
||||||
|
|
|
@ -1,36 +1,16 @@
|
||||||
package com.simibubi.create.compat.jei.category;
|
package com.simibubi.create.compat.jei.category;
|
||||||
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
|
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.item.crafting.SmokingRecipe;
|
import net.minecraft.item.crafting.SmokingRecipe;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class SmokingViaFanCategory extends ProcessingViaFanCategory<SmokingRecipe> {
|
public class SmokingViaFanCategory extends ProcessingViaFanCategory<SmokingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "smoking_via_fan");
|
|
||||||
private IDrawable icon;
|
|
||||||
|
|
||||||
public SmokingViaFanCategory() {
|
public SmokingViaFanCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()),
|
super("smoking_via_fan", doubleItemIcon(AllItems.PROPELLER.get(), Items.BLAZE_POWDER));
|
||||||
() -> new ItemStack(Items.BLAZE_POWDER));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,11 +18,6 @@ public class SmokingViaFanCategory extends ProcessingViaFanCategory<SmokingRecip
|
||||||
return SmokingRecipe.class;
|
return SmokingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.smokingViaFan");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAttachedBlock() {
|
public void renderAttachedBlock() {
|
||||||
ScreenElementRenderer.renderBlock(() -> Blocks.FIRE.getDefaultState());
|
ScreenElementRenderer.renderBlock(() -> Blocks.FIRE.getDefaultState());
|
||||||
|
|
|
@ -5,52 +5,24 @@ import java.util.List;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.ScreenResources;
|
import com.simibubi.create.ScreenResources;
|
||||||
import com.simibubi.create.compat.jei.CreateJEI;
|
|
||||||
import com.simibubi.create.compat.jei.DoubleItemIcon;
|
|
||||||
import com.simibubi.create.compat.jei.EmptyBackground;
|
|
||||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.fan.SplashingRecipe;
|
import com.simibubi.create.modules.contraptions.components.fan.SplashingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
|
||||||
|
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.gui.drawable.IDrawable;
|
|
||||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||||
import mezz.jei.api.ingredients.IIngredients;
|
import mezz.jei.api.ingredients.IIngredients;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.FlowingFluidBlock;
|
import net.minecraft.block.FlowingFluidBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe> {
|
public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe> {
|
||||||
|
|
||||||
private static ResourceLocation ID = new ResourceLocation(Create.ID, "splashing");
|
|
||||||
private IDrawable icon;
|
|
||||||
private IDrawable background = new EmptyBackground(177, 70);
|
|
||||||
|
|
||||||
public SplashingCategory() {
|
public SplashingCategory() {
|
||||||
icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()),
|
super("splashing", doubleItemIcon(AllItems.PROPELLER.get(), Items.WATER_BUCKET));
|
||||||
() -> new ItemStack(Items.WATER_BUCKET));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getBackground() {
|
|
||||||
return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IDrawable getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getUid() {
|
|
||||||
return ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,11 +30,6 @@ public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe>
|
||||||
return SplashingRecipe.class;
|
return SplashingRecipe.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return Lang.translate("recipe.splashing");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIngredients(SplashingRecipe recipe, IIngredients ingredients) {
|
public void setIngredients(SplashingRecipe recipe, IIngredients ingredients) {
|
||||||
ingredients.setInputIngredients(recipe.getIngredients());
|
ingredients.setInputIngredients(recipe.getIngredients());
|
||||||
|
@ -85,7 +52,7 @@ public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe>
|
||||||
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateJEI.addStochasticTooltip(itemStacks, results);
|
addStochasticTooltip(itemStacks, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,14 +64,15 @@ public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe>
|
||||||
ScreenResources.JEI_SHADOW.draw(66, 39);
|
ScreenResources.JEI_SHADOW.draw(66, 39);
|
||||||
ScreenResources.JEI_LONG_ARROW.draw(53, 51);
|
ScreenResources.JEI_LONG_ARROW.draw(53, 51);
|
||||||
|
|
||||||
if (size > 1) {
|
if (size == 1) {
|
||||||
for (int i = 0; i < size; i++) {
|
getRenderedSlot(recipe, 0).draw(139, 47);
|
||||||
int xOffset = i % 2 == 0 ? 0 : 19;
|
return;
|
||||||
int yOffset = (i / 2) * -19;
|
}
|
||||||
ScreenResources.JEI_SLOT.draw(133 + xOffset, 47 + yOffset);
|
|
||||||
}
|
for (int i = 0; i < size; i++) {
|
||||||
} else {
|
int xOffset = i % 2 == 0 ? 0 : 19;
|
||||||
ScreenResources.JEI_SLOT.draw(139, 47);
|
int yOffset = (i / 2) * -19;
|
||||||
|
getRenderedSlot(recipe, i).draw(133 + xOffset, 47 + yOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ public class CClient extends ConfigBase {
|
||||||
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");
|
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");
|
||||||
public ConfigBool rainbowDebug =
|
public ConfigBool rainbowDebug =
|
||||||
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");
|
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");
|
||||||
|
public ConfigBool showHiddenSuperGlue =
|
||||||
|
b(false, "showHiddenSuperGlue", "Show indications for hidden glue between blocks while holding the item.");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
|
@ -5,9 +5,9 @@ public class CDamageControl extends ConfigBase {
|
||||||
public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing);
|
public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing);
|
||||||
public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors);
|
public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors);
|
||||||
public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing);
|
public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing);
|
||||||
public ConfigBool freezeRotationPropagator = b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
public ConfigBool freezeRotationPropagator =
|
||||||
public ConfigBool freezeBearingConstructs = b(false, "freezeBearingConstructs", Comments.freezeBearingConstructs);
|
b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
||||||
public ConfigBool freezePistonConstructs = b(false, "freezePistonConstructs", Comments.freezePistonConstructs);
|
public ConfigBool freezeContraptions = b(false, "freezeContraptions", Comments.freezeContraptions);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -20,8 +20,7 @@ public class CDamageControl extends ConfigBase {
|
||||||
static String freezeInWorldProcessing = "In case Encased Fans tried smelting your hardware.";
|
static String freezeInWorldProcessing = "In case Encased Fans tried smelting your hardware.";
|
||||||
static String freezeRotationPropagator =
|
static String freezeRotationPropagator =
|
||||||
"Pauses rotation logic altogether - Use if crash mentions RotationPropagators.";
|
"Pauses rotation logic altogether - Use if crash mentions RotationPropagators.";
|
||||||
static String freezeBearingConstructs = "In case Mechanical Bearings turned against you.";
|
static String freezeContraptions = "In case Moving contraptions pushed it too far.";
|
||||||
static String freezePistonConstructs = "In case Mechanical Pistons pushed it too far.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,8 @@ public class ValueBoxRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
box.render(highlighted);
|
box.render(highlighted);
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
RenderSystem.disableAlphaTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderText(ValueBox box, FontRenderer font, String text) {
|
public static void renderText(ValueBox box, FontRenderer font, String text) {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.simibubi.create.foundation.behaviour.base;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public abstract class PosBoundSmartTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
|
private boolean newPositionVisited;
|
||||||
|
|
||||||
|
public PosBoundSmartTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||||
|
super(tileEntityTypeIn);
|
||||||
|
newPositionVisited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
if (!world.isRemote && newPositionVisited) {
|
||||||
|
newPositionVisited = false;
|
||||||
|
initInNewPosition();
|
||||||
|
}
|
||||||
|
super.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT compound) {
|
||||||
|
long positionInTag = new BlockPos(compound.getInt("x"), compound.getInt("y"), compound.getInt("z")).toLong();
|
||||||
|
long positionKey = compound.getLong("BoundPosition");
|
||||||
|
|
||||||
|
newPositionVisited = false;
|
||||||
|
if (!hasWorld() || !world.isRemote) {
|
||||||
|
if (positionInTag != positionKey) {
|
||||||
|
removePositionDependentData(compound);
|
||||||
|
newPositionVisited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.read(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-only. When this TE realizes, that it's reading its tag in a different
|
||||||
|
* position, it should remove all position dependent information here.
|
||||||
|
*
|
||||||
|
* @param nbt
|
||||||
|
*/
|
||||||
|
protected void removePositionDependentData(CompoundNBT nbt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-only. When a TE has been created or moved, it will call this before the
|
||||||
|
* regular init.
|
||||||
|
*/
|
||||||
|
protected void initInNewPosition() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -86,8 +86,9 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
||||||
list.forEach(b -> behaviours.put(b.getType(), b));
|
list.forEach(b -> behaviours.put(b.getType(), b));
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachBehaviour(tb -> tb.readNBT(compound));
|
|
||||||
super.read(compound);
|
super.read(compound);
|
||||||
|
forEachBehaviour(tb -> tb.readNBT(compound));
|
||||||
|
|
||||||
if (world != null && world.isRemote)
|
if (world != null && world.isRemote)
|
||||||
updateClient(compound);
|
updateClient(compound);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
filter = ItemStack.EMPTY;
|
filter = ItemStack.EMPTY;
|
||||||
slotPositioning = slot;
|
slotPositioning = slot;
|
||||||
showCount = false;
|
showCount = false;
|
||||||
callback = stack -> {
|
callback = stack -> {};
|
||||||
};
|
|
||||||
textShift = Vec3d.ZERO;
|
textShift = Vec3d.ZERO;
|
||||||
count = 0;
|
count = 0;
|
||||||
ticksUntilScrollPacket = -1;
|
ticksUntilScrollPacket = -1;
|
||||||
|
@ -114,11 +113,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
public void setFilter(ItemStack stack) {
|
public void setFilter(ItemStack stack) {
|
||||||
filter = stack.copy();
|
filter = stack.copy();
|
||||||
callback.accept(filter);
|
callback.accept(filter);
|
||||||
|
count = (filter.getItem() instanceof FilterItem) ? 0 : Math.min(stack.getCount(), stack.getMaxStackSize());
|
||||||
if (filter.getItem() instanceof FilterItem)
|
|
||||||
count = 0;
|
|
||||||
else
|
|
||||||
count = stack.getCount();
|
|
||||||
forceClientState = true;
|
forceClientState = true;
|
||||||
|
|
||||||
tileEntity.markDirty();
|
tileEntity.markDirty();
|
||||||
|
|
|
@ -87,12 +87,14 @@ public class FilteringHandler {
|
||||||
return false;
|
return false;
|
||||||
if (!filtering.testHit(objectMouseOver.getHitVec()))
|
if (!filtering.testHit(objectMouseOver.getHitVec()))
|
||||||
return false;
|
return false;
|
||||||
if (filtering.getFilter().isEmpty())
|
ItemStack filterItem = filtering.getFilter();
|
||||||
|
if (filterItem.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
filtering.ticksUntilScrollPacket = 10;
|
filtering.ticksUntilScrollPacket = 10;
|
||||||
filtering.scrollableValue = (int) MathHelper
|
int maxAmount = (filterItem.getItem() instanceof FilterItem) ? 64 : filterItem.getMaxStackSize();
|
||||||
.clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, 64);
|
filtering.scrollableValue =
|
||||||
|
(int) MathHelper.clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, maxAmount);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
ValueBoxTransform secondSlot;
|
ValueBoxTransform secondSlot;
|
||||||
Vec3d textShift;
|
Vec3d textShift;
|
||||||
|
|
||||||
|
public boolean newPosition;
|
||||||
private Mode mode;
|
private Mode mode;
|
||||||
private Supplier<Boolean> transmission;
|
private Supplier<Boolean> transmission;
|
||||||
private Consumer<Boolean> signalCallback;
|
private Consumer<Boolean> signalCallback;
|
||||||
|
@ -45,6 +46,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
firstSlot = slots.getLeft();
|
firstSlot = slots.getLeft();
|
||||||
secondSlot = slots.getRight();
|
secondSlot = slots.getRight();
|
||||||
textShift = Vec3d.ZERO;
|
textShift = Vec3d.ZERO;
|
||||||
|
newPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
|
public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
|
||||||
|
@ -84,6 +86,8 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateReceiver(boolean networkPowered) {
|
public void updateReceiver(boolean networkPowered) {
|
||||||
|
if (!newPosition)
|
||||||
|
return;
|
||||||
signalCallback.accept(networkPowered);
|
signalCallback.accept(networkPowered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +101,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
if (tileEntity.getWorld().isRemote)
|
if (tileEntity.getWorld().isRemote)
|
||||||
return;
|
return;
|
||||||
getHandler().addToNetwork(this);
|
getHandler().addToNetwork(this);
|
||||||
|
newPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Frequency, Frequency> getNetworkKey() {
|
public Pair<Frequency, Frequency> getNetworkKey() {
|
||||||
|
@ -116,10 +121,15 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
super.writeNBT(compound);
|
super.writeNBT(compound);
|
||||||
compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT()));
|
compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT()));
|
||||||
compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT()));
|
compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT()));
|
||||||
|
compound.putLong("LastKnownPosition", tileEntity.getPos().toLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readNBT(CompoundNBT compound) {
|
public void readNBT(CompoundNBT compound) {
|
||||||
|
long positionInTag = tileEntity.getPos().toLong();
|
||||||
|
long positionKey = compound.getLong("LastKnownPosition");
|
||||||
|
newPosition = positionInTag != positionKey;
|
||||||
|
|
||||||
super.readNBT(compound);
|
super.readNBT(compound);
|
||||||
frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst")));
|
frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst")));
|
||||||
frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast")));
|
frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast")));
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.foundation.behaviour.scrollvalue;
|
package com.simibubi.create.foundation.behaviour.scrollvalue;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllKeys;
|
import com.simibubi.create.AllKeys;
|
||||||
|
@ -60,7 +62,10 @@ public class ScrollValueRenderer {
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
render(world, pos, face, behaviour, highlight);
|
render(world, pos, face, behaviour, highlight);
|
||||||
|
|
||||||
TessellatorHelper.cleanUpAfterDrawing();
|
TessellatorHelper.cleanUpAfterDrawing();
|
||||||
|
RenderSystem.enableAlphaTest();
|
||||||
|
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour,
|
protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour,
|
||||||
|
|
|
@ -3,12 +3,9 @@ package com.simibubi.create.foundation.block.render;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
|
||||||
import net.minecraft.client.renderer.model.BakedQuad;
|
import net.minecraft.client.renderer.model.BakedQuad;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||||
|
|
|
@ -2,8 +2,6 @@ package com.simibubi.create.foundation.gui;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
|
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
|
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
|
||||||
|
@ -16,15 +14,13 @@ import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.FireBlock;
|
import net.minecraft.block.FireBlock;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderHelper;
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -79,7 +75,7 @@ public class ScreenElementRenderer {
|
||||||
boolean stateMode = transformsAndModel == null;
|
boolean stateMode = transformsAndModel == null;
|
||||||
boolean fire = false;
|
boolean fire = false;
|
||||||
|
|
||||||
if (stateMode) {
|
if (transformsAndModel == null) {
|
||||||
blockToRender = transformsAndState.get();
|
blockToRender = transformsAndState.get();
|
||||||
fire = (blockToRender.getBlock() instanceof FireBlock);
|
fire = (blockToRender.getBlock() instanceof FireBlock);
|
||||||
modelToRender = blockRenderer.getModelForState(blockToRender);
|
modelToRender = blockRenderer.getModelForState(blockToRender);
|
||||||
|
@ -92,6 +88,7 @@ public class ScreenElementRenderer {
|
||||||
RenderType renderType = RenderTypeLookup.getEntityBlockLayer(blockToRender);
|
RenderType renderType = RenderTypeLookup.getEntityBlockLayer(blockToRender);
|
||||||
IVertexBuilder vb = buffer.getBuffer(renderType);
|
IVertexBuilder vb = buffer.getBuffer(renderType);
|
||||||
MatrixStack ms = new MatrixStack();
|
MatrixStack ms = new MatrixStack();
|
||||||
|
mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||||
|
|
||||||
RenderSystem.pushMatrix();
|
RenderSystem.pushMatrix();
|
||||||
if (fire) {
|
if (fire) {
|
||||||
|
@ -111,7 +108,7 @@ public class ScreenElementRenderer {
|
||||||
}
|
}
|
||||||
RenderSystem.popMatrix();
|
RenderSystem.popMatrix();
|
||||||
|
|
||||||
if (stateMode && !blockToRender.getFluidState().isEmpty()) {
|
if (blockToRender != null && !blockToRender.getFluidState().isEmpty()) {
|
||||||
RenderHelper.disableStandardItemLighting();
|
RenderHelper.disableStandardItemLighting();
|
||||||
RenderSystem.translatef(0, -300, 0);
|
RenderSystem.translatef(0, -300, 0);
|
||||||
blockRenderer.renderFluid(new BlockPos(0, 300, 0), mc.world, vb, blockToRender.getFluidState());
|
blockRenderer.renderFluid(new BlockPos(0, 300, 0), mc.world, vb, blockToRender.getFluidState());
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.simibubi.create.foundation.gui.widgets;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
|
||||||
|
public class InterpolatedChasingAngle extends InterpolatedChasingValue {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getCurrentDiff() {
|
||||||
|
return AngleHelper.getShortestAngleDiff(value, getTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,12 +7,16 @@ public class InterpolatedChasingValue extends InterpolatedValue {
|
||||||
float eps = 1 / 4096f;
|
float eps = 1 / 4096f;
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
float diff = target - value;
|
float diff = getCurrentDiff();
|
||||||
if (Math.abs(diff) < eps)
|
if (Math.abs(diff) < eps)
|
||||||
return;
|
return;
|
||||||
set(value + (diff) * speed);
|
set(value + (diff) * speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected float getCurrentDiff() {
|
||||||
|
return getTarget() - value;
|
||||||
|
}
|
||||||
|
|
||||||
public InterpolatedChasingValue withSpeed(float speed) {
|
public InterpolatedChasingValue withSpeed(float speed) {
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
return this;
|
return this;
|
||||||
|
@ -23,4 +27,14 @@ public class InterpolatedChasingValue extends InterpolatedValue {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InterpolatedChasingValue start(float value) {
|
||||||
|
lastValue = this.value = value;
|
||||||
|
target(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@ public class AngleHelper {
|
||||||
return (float) (angle * 180 / Math.PI);
|
return (float) (angle * 180 / Math.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float angleLerp(float pct, float current, float target) {
|
public static float angleLerp(float pct, float current, float target) {
|
||||||
return current + getShortestAngleDiff(current, target) * pct;
|
return current + getShortestAngleDiff(current, target) * pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float getShortestAngleDiff(double current, double target) {
|
public static float getShortestAngleDiff(double current, double target) {
|
||||||
current = current % 360;
|
current = current % 360;
|
||||||
target = target % 360;
|
target = target % 360;
|
||||||
return (float) (((((target - current) % 360) + 540) % 360) - 180);
|
return (float) (((((target - current) % 360) + 540) % 360) - 180);
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
import static net.minecraft.util.Direction.*;
|
import static net.minecraft.util.Direction.DOWN;
|
||||||
|
import static net.minecraft.util.Direction.EAST;
|
||||||
|
import static net.minecraft.util.Direction.NORTH;
|
||||||
|
import static net.minecraft.util.Direction.SOUTH;
|
||||||
|
import static net.minecraft.util.Direction.UP;
|
||||||
|
import static net.minecraft.util.Direction.WEST;
|
||||||
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -20,4 +22,14 @@ public class GlHelper {
|
||||||
RenderSystem.popMatrix();
|
RenderSystem.popMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void enableTextureRepeat() {
|
||||||
|
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT);
|
||||||
|
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disableTextureRepeat() {
|
||||||
|
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_CLAMP);
|
||||||
|
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_CLAMP);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.entity.MobEntity;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
public class Iterate {
|
public class Iterate {
|
||||||
|
|
||||||
public static final boolean[] trueAndFalse = { true, false };
|
public static final boolean[] trueAndFalse = { true, false };
|
||||||
|
public static final int[] zeroAndOne = { 1, -1 };
|
||||||
public static final int[] positiveAndNegative = { 1, -1 };
|
public static final int[] positiveAndNegative = { 1, -1 };
|
||||||
public static final Direction[] directions = Direction.values();
|
public static final Direction[] directions = Direction.values();
|
||||||
public static final Direction[] horizontalDirections = getHorizontals();
|
public static final Direction[] horizontalDirections = getHorizontals();
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
|
||||||
|
public class RayTraceWorld implements IBlockReader {
|
||||||
|
|
||||||
|
private IWorld template;
|
||||||
|
private BiFunction<BlockPos, BlockState, BlockState> stateGetter;
|
||||||
|
|
||||||
|
public RayTraceWorld(IWorld template, BiFunction<BlockPos, BlockState, BlockState> stateGetter) {
|
||||||
|
this.template = template;
|
||||||
|
this.stateGetter = stateGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
return template.getTileEntity(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
return stateGetter.apply(pos, template.getBlockState(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IFluidState getFluidState(BlockPos pos) {
|
||||||
|
return template.getFluidState(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,13 +22,14 @@ public class RaycastHelper {
|
||||||
return worldIn.rayTraceBlocks(context);
|
return worldIn.rayTraceBlocks(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PredicateTraceResult rayTraceUntil(PlayerEntity playerIn, double range, Predicate<BlockPos> predicate) {
|
public static PredicateTraceResult rayTraceUntil(PlayerEntity playerIn, double range,
|
||||||
|
Predicate<BlockPos> predicate) {
|
||||||
Vec3d origin = getTraceOrigin(playerIn);
|
Vec3d origin = getTraceOrigin(playerIn);
|
||||||
Vec3d target = getTraceTarget(playerIn, range, origin);
|
Vec3d target = getTraceTarget(playerIn, range, origin);
|
||||||
return rayTraceUntil(origin, target, predicate);
|
return rayTraceUntil(origin, target, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vec3d getTraceTarget(PlayerEntity playerIn, double range, Vec3d origin) {
|
public static Vec3d getTraceTarget(PlayerEntity playerIn, double range, Vec3d origin) {
|
||||||
float f = playerIn.rotationPitch;
|
float f = playerIn.rotationPitch;
|
||||||
float f1 = playerIn.rotationYaw;
|
float f1 = playerIn.rotationYaw;
|
||||||
float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI);
|
float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI);
|
||||||
|
@ -42,7 +43,7 @@ public class RaycastHelper {
|
||||||
return vec3d1;
|
return vec3d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vec3d getTraceOrigin(PlayerEntity playerIn) {
|
public static Vec3d getTraceOrigin(PlayerEntity playerIn) {
|
||||||
double d0 = playerIn.getX();
|
double d0 = playerIn.getX();
|
||||||
double d1 = playerIn.getY() + (double) playerIn.getEyeHeight();
|
double d1 = playerIn.getY() + (double) playerIn.getEyeHeight();
|
||||||
double d2 = playerIn.getZ();
|
double d2 = playerIn.getZ();
|
||||||
|
@ -50,7 +51,7 @@ public class RaycastHelper {
|
||||||
return vec3d;
|
return vec3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PredicateTraceResult rayTraceUntil(Vec3d start, Vec3d end, Predicate<BlockPos> predicate) {
|
public static PredicateTraceResult rayTraceUntil(Vec3d start, Vec3d end, Predicate<BlockPos> predicate) {
|
||||||
if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z))
|
if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z))
|
||||||
return null;
|
return null;
|
||||||
if (Double.isNaN(end.x) || Double.isNaN(end.y) || Double.isNaN(end.z))
|
if (Double.isNaN(end.x) || Double.isNaN(end.y) || Double.isNaN(end.z))
|
||||||
|
|
|
@ -10,10 +10,10 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.BufferBuilder.DrawState;
|
import net.minecraft.client.renderer.BufferBuilder.DrawState;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
||||||
import net.minecraft.client.renderer.GLAllocation;
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
import net.minecraft.client.renderer.Vector4f;
|
import net.minecraft.client.renderer.Vector4f;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
|
|
@ -27,9 +27,7 @@ public class TessellatorHelper {
|
||||||
RenderSystem.pushMatrix();
|
RenderSystem.pushMatrix();
|
||||||
RenderSystem.pushLightingAttributes();
|
RenderSystem.pushLightingAttributes();
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.enableAlphaTest();
|
|
||||||
RenderSystem.color4f(1, 1, 1, 1);
|
RenderSystem.color4f(1, 1, 1, 1);
|
||||||
|
|
||||||
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
|
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
|
||||||
Vec3d view = renderInfo.getProjectedView();
|
Vec3d view = renderInfo.getProjectedView();
|
||||||
RenderSystem.translated(-view.x, -view.y, -view.z);
|
RenderSystem.translated(-view.x, -view.y, -view.z);
|
||||||
|
@ -83,10 +81,9 @@ public class TessellatorHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void cleanUpAfterDrawing() {
|
public static void cleanUpAfterDrawing() {
|
||||||
RenderSystem.disableAlphaTest();
|
|
||||||
RenderSystem.disableBlend();
|
|
||||||
RenderSystem.popAttributes();
|
RenderSystem.popAttributes();
|
||||||
RenderSystem.popMatrix();
|
RenderSystem.popMatrix();
|
||||||
|
RenderSystem.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawString(String str, float x, float y, float z, boolean scalesUp, boolean hasDepth) {
|
public static void drawString(String str, float x, float y, float z, boolean scalesUp, boolean hasDepth) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -8,8 +9,16 @@ import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
|
||||||
|
import net.minecraft.block.BambooBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.CactusBlock;
|
||||||
|
import net.minecraft.block.ChorusFlowerBlock;
|
||||||
|
import net.minecraft.block.ChorusPlantBlock;
|
||||||
|
import net.minecraft.block.KelpBlock;
|
||||||
|
import net.minecraft.block.KelpTopBlock;
|
||||||
import net.minecraft.block.LeavesBlock;
|
import net.minecraft.block.LeavesBlock;
|
||||||
|
import net.minecraft.block.SugarCaneBlock;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -40,6 +49,41 @@ public class TreeCutter {
|
||||||
Set<BlockPos> visited = new HashSet<>();
|
Set<BlockPos> visited = new HashSet<>();
|
||||||
List<BlockPos> frontier = new LinkedList<>();
|
List<BlockPos> frontier = new LinkedList<>();
|
||||||
|
|
||||||
|
// Bamboo, Sugar Cane, Cactus
|
||||||
|
BlockState stateAbove = reader.getBlockState(pos.up());
|
||||||
|
if (isVerticalPlant(stateAbove)) {
|
||||||
|
logs.add(pos.up());
|
||||||
|
for (int i = 1; i < 256; i++) {
|
||||||
|
BlockPos current = pos.up(i);
|
||||||
|
if (!isVerticalPlant(reader.getBlockState(current)))
|
||||||
|
break;
|
||||||
|
logs.add(current);
|
||||||
|
}
|
||||||
|
Collections.reverse(logs);
|
||||||
|
return new Tree(logs, leaves);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chorus
|
||||||
|
if (isChorus(stateAbove)) {
|
||||||
|
frontier.add(pos.up());
|
||||||
|
while (!frontier.isEmpty()) {
|
||||||
|
BlockPos current = frontier.remove(0);
|
||||||
|
visited.add(current);
|
||||||
|
logs.add(current);
|
||||||
|
for (Direction direction : Iterate.directions) {
|
||||||
|
BlockPos offset = current.offset(direction);
|
||||||
|
if (visited.contains(offset))
|
||||||
|
continue;
|
||||||
|
if (!isChorus(reader.getBlockState(offset)))
|
||||||
|
continue;
|
||||||
|
frontier.add(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.reverse(logs);
|
||||||
|
return new Tree(logs, leaves);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular Tree
|
||||||
if (!validateCut(reader, pos))
|
if (!validateCut(reader, pos))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -94,6 +138,25 @@ public class TreeCutter {
|
||||||
return new Tree(logs, leaves);
|
return new Tree(logs, leaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isChorus(BlockState stateAbove) {
|
||||||
|
return stateAbove.getBlock() instanceof ChorusPlantBlock || stateAbove.getBlock() instanceof ChorusFlowerBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isVerticalPlant(BlockState stateAbove) {
|
||||||
|
Block block = stateAbove.getBlock();
|
||||||
|
if (block instanceof BambooBlock)
|
||||||
|
return true;
|
||||||
|
if (block instanceof CactusBlock)
|
||||||
|
return true;
|
||||||
|
if (block instanceof SugarCaneBlock)
|
||||||
|
return true;
|
||||||
|
if (block instanceof KelpBlock)
|
||||||
|
return true;
|
||||||
|
if (block instanceof KelpTopBlock)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a tree was fully cut by seeing whether the layer above the cut
|
* Checks whether a tree was fully cut by seeing whether the layer above the cut
|
||||||
* is not supported by any more logs.
|
* is not supported by any more logs.
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -11,6 +12,7 @@ import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.item.crafting.RecipeManager;
|
import net.minecraft.item.crafting.RecipeManager;
|
||||||
import net.minecraft.scoreboard.Scoreboard;
|
import net.minecraft.scoreboard.Scoreboard;
|
||||||
import net.minecraft.tags.NetworkTagManager;
|
import net.minecraft.tags.NetworkTagManager;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -34,6 +36,26 @@ public class WrappedWorld extends World {
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
return world.getBlockState(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasBlockState(BlockPos p_217375_1_, Predicate<BlockState> p_217375_2_) {
|
||||||
|
return world.hasBlockState(p_217375_1_, p_217375_2_);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
return world.getTileEntity(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlockState(BlockPos pos, BlockState newState, int flags) {
|
||||||
|
return world.setBlockState(pos, newState, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLight(BlockPos pos) {
|
public int getLight(BlockPos pos) {
|
||||||
return 15;
|
return 15;
|
||||||
|
@ -55,8 +77,7 @@ public class WrappedWorld extends World {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) {
|
public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends PlayerEntity> getPlayers() {
|
public List<? extends PlayerEntity> getPlayers() {
|
||||||
|
@ -65,13 +86,11 @@ public class WrappedWorld extends World {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSound(PlayerEntity player, double x, double y, double z, SoundEvent soundIn, SoundCategory category,
|
public void playSound(PlayerEntity player, double x, double y, double z, SoundEvent soundIn, SoundCategory category,
|
||||||
float volume, float pitch) {
|
float volume, float pitch) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playMovingSound(PlayerEntity p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_,
|
public void playMovingSound(PlayerEntity p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_,
|
||||||
SoundCategory p_217384_4_, float p_217384_5_, float p_217384_6_) {
|
SoundCategory p_217384_4_, float p_217384_5_, float p_217384_6_) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity getEntityByID(int id) {
|
public Entity getEntityByID(int id) {
|
||||||
|
@ -90,8 +109,7 @@ public class WrappedWorld extends World {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMapData(MapData mapDataIn) {
|
public void registerMapData(MapData mapDataIn) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNextMapId() {
|
public int getNextMapId() {
|
||||||
|
@ -99,8 +117,7 @@ public class WrappedWorld extends World {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {
|
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Scoreboard getScoreboard() {
|
public Scoreboard getScoreboard() {
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
package com.simibubi.create.foundation.utility.outliner;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
import com.simibubi.create.AllSpecialTextures;
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class AABBOutline extends Outline {
|
||||||
|
|
||||||
|
protected AxisAlignedBB bb;
|
||||||
|
protected AllSpecialTextures faceTexture;
|
||||||
|
protected AllSpecialTextures highlightedTexture;
|
||||||
|
protected Direction highlightedFace;
|
||||||
|
public boolean disableCull = false;
|
||||||
|
|
||||||
|
public AABBOutline(AxisAlignedBB bb) {
|
||||||
|
this.bb = bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(BufferBuilder buffer) {
|
||||||
|
Vec3d color = ColorHelper.getRGB(0xFFFFFF);
|
||||||
|
float alpha = 1f;
|
||||||
|
renderBB(bb, buffer, color, alpha, !disableCull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) {
|
||||||
|
this.faceTexture = faceTexture;
|
||||||
|
this.highlightedTexture = highlightTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void highlightFace(Direction face) {
|
||||||
|
this.highlightedFace = face;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderBB(AxisAlignedBB bb, IVertexBuilder builder, Vec3d color, float alpha, boolean doCulling) {
|
||||||
|
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||||
|
boolean inside = bb.contains(projectedView);
|
||||||
|
bb = bb.grow(inside ? -1 / 128d : 1 / 128d);
|
||||||
|
|
||||||
|
Vec3d xyz = new Vec3d(bb.minX, bb.minY, bb.minZ);
|
||||||
|
Vec3d Xyz = new Vec3d(bb.maxX, bb.minY, bb.minZ);
|
||||||
|
Vec3d xYz = new Vec3d(bb.minX, bb.maxY, bb.minZ);
|
||||||
|
Vec3d XYz = new Vec3d(bb.maxX, bb.maxY, bb.minZ);
|
||||||
|
Vec3d xyZ = new Vec3d(bb.minX, bb.minY, bb.maxZ);
|
||||||
|
Vec3d XyZ = new Vec3d(bb.maxX, bb.minY, bb.maxZ);
|
||||||
|
Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ);
|
||||||
|
Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ);
|
||||||
|
|
||||||
|
renderFace(Direction.NORTH, xYz, XYz, Xyz, xyz, builder);
|
||||||
|
renderFace(Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, builder);
|
||||||
|
renderFace(Direction.EAST, XYz, XYZ, XyZ, Xyz, builder);
|
||||||
|
renderFace(Direction.WEST, xYZ, xYz, xyz, xyZ, builder);
|
||||||
|
renderFace(Direction.UP, xYZ, XYZ, XYz, xYz, builder);
|
||||||
|
renderFace(Direction.DOWN, xyz, Xyz, XyZ, xyZ, builder);
|
||||||
|
|
||||||
|
Vec3d start = xyz;
|
||||||
|
AllSpecialTextures.BLANK.bind();
|
||||||
|
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||||
|
|
||||||
|
start = XyZ;
|
||||||
|
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||||
|
|
||||||
|
start = XYz;
|
||||||
|
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||||
|
|
||||||
|
start = xYZ;
|
||||||
|
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||||
|
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, IVertexBuilder builder) {
|
||||||
|
if (direction == highlightedFace && highlightedTexture != null)
|
||||||
|
highlightedTexture.bind();
|
||||||
|
else if (faceTexture != null)
|
||||||
|
faceTexture.bind();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vec3d uDiff = p2.subtract(p1);
|
||||||
|
Vec3d vDiff = p4.subtract(p1);
|
||||||
|
Axis axis = direction.getAxis();
|
||||||
|
float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
|
||||||
|
float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
|
||||||
|
putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package com.simibubi.create.foundation.utility.outliner;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllSpecialTextures;
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Direction.AxisDirection;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class BlockClusterOutline extends Outline {
|
||||||
|
|
||||||
|
private Cluster cluster;
|
||||||
|
private float alpha;
|
||||||
|
|
||||||
|
public BlockClusterOutline(Iterable<BlockPos> selection) {
|
||||||
|
cluster = new Cluster();
|
||||||
|
selection.forEach(cluster::include);
|
||||||
|
alpha = .5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(BufferBuilder buffer) {
|
||||||
|
Vec3d color = ColorHelper.getRGB(0xDDDDDD);
|
||||||
|
AllSpecialTextures.SELECTION.bind();
|
||||||
|
|
||||||
|
for (MergeEntry face : cluster.visibleFaces.keySet()) {
|
||||||
|
AxisDirection axisDirection = cluster.visibleFaces.get(face);
|
||||||
|
Direction direction = Direction.getFacingFromAxis(axisDirection, face.axis);
|
||||||
|
BlockPos pos = face.pos;
|
||||||
|
if (axisDirection == AxisDirection.POSITIVE)
|
||||||
|
pos = pos.offset(direction.getOpposite());
|
||||||
|
renderFace(pos, direction, color, alpha * .25f, 1 / 64d, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
AllSpecialTextures.BLANK.bind();
|
||||||
|
|
||||||
|
for (MergeEntry edge : cluster.visibleEdges) {
|
||||||
|
lineWidth = 1 / 16f * alpha;
|
||||||
|
Vec3d start = new Vec3d(edge.pos);
|
||||||
|
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis);
|
||||||
|
renderAACuboidLine(start, new Vec3d(edge.pos.offset(direction)), color, 1, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlpha(float alpha) {
|
||||||
|
this.alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Cluster {
|
||||||
|
|
||||||
|
Map<MergeEntry, AxisDirection> visibleFaces;
|
||||||
|
Set<MergeEntry> visibleEdges;
|
||||||
|
|
||||||
|
public Cluster() {
|
||||||
|
visibleEdges = new HashSet<>();
|
||||||
|
visibleFaces = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void include(BlockPos pos) {
|
||||||
|
|
||||||
|
// 6 FACES
|
||||||
|
for (Axis axis : Axis.values()) {
|
||||||
|
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
|
||||||
|
for (int offset : new int[] { 0, 1 }) {
|
||||||
|
MergeEntry entry = new MergeEntry(axis, pos.offset(direction, offset));
|
||||||
|
if (visibleFaces.remove(entry) == null)
|
||||||
|
visibleFaces.put(entry, offset == 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12 EDGES
|
||||||
|
for (Axis axis : Axis.values()) {
|
||||||
|
for (Axis axis2 : Axis.values()) {
|
||||||
|
if (axis == axis2)
|
||||||
|
continue;
|
||||||
|
for (Axis axis3 : Axis.values()) {
|
||||||
|
if (axis == axis3)
|
||||||
|
continue;
|
||||||
|
if (axis2 == axis3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis2);
|
||||||
|
Direction direction2 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis3);
|
||||||
|
|
||||||
|
for (int offset : new int[] { 0, 1 }) {
|
||||||
|
BlockPos entryPos = pos.offset(direction, offset);
|
||||||
|
for (int offset2 : new int[] { 0, 1 }) {
|
||||||
|
entryPos = entryPos.offset(direction2, offset2);
|
||||||
|
MergeEntry entry = new MergeEntry(axis, entryPos);
|
||||||
|
if (!visibleEdges.remove(entry))
|
||||||
|
visibleEdges.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MergeEntry {
|
||||||
|
|
||||||
|
Axis axis;
|
||||||
|
BlockPos pos;
|
||||||
|
|
||||||
|
public MergeEntry(Axis axis, BlockPos pos) {
|
||||||
|
this.axis = axis;
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof MergeEntry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MergeEntry other = (MergeEntry) o;
|
||||||
|
return this.axis == other.axis && this.pos.equals(other.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.pos.hashCode() * 31 + axis.ordinal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.simibubi.create.foundation.utility.outliner;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class ChasingAABBOutline extends AABBOutline {
|
||||||
|
|
||||||
|
AxisAlignedBB targetBB;
|
||||||
|
AxisAlignedBB prevBB;
|
||||||
|
|
||||||
|
public ChasingAABBOutline(AxisAlignedBB bb) {
|
||||||
|
super(bb);
|
||||||
|
prevBB = bb.grow(0);
|
||||||
|
targetBB = bb.grow(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void target(AxisAlignedBB target) {
|
||||||
|
targetBB = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
prevBB = bb;
|
||||||
|
bb = interpolateBBs(bb, targetBB, .5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(BufferBuilder buffer) {
|
||||||
|
Vec3d color = ColorHelper.getRGB(0xFFFFFF);
|
||||||
|
float alpha = 1f;
|
||||||
|
renderBB(interpolateBBs(prevBB, bb, Minecraft.getInstance().getRenderPartialTicks()), buffer, color, alpha,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) {
|
||||||
|
return new AxisAlignedBB(MathHelper.lerp(pt, current.minX, target.minX),
|
||||||
|
MathHelper.lerp(pt, current.minY, target.minY), MathHelper.lerp(pt, current.minZ, target.minZ),
|
||||||
|
MathHelper.lerp(pt, current.maxX, target.maxX), MathHelper.lerp(pt, current.maxY, target.maxY),
|
||||||
|
MathHelper.lerp(pt, current.maxZ, target.maxZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.simibubi.create.foundation.utility.outliner;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public abstract class Outline {
|
||||||
|
|
||||||
|
protected float lineWidth = 1 / 32f;
|
||||||
|
|
||||||
|
public abstract void render(BufferBuilder buffer);
|
||||||
|
|
||||||
|
public void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, IVertexBuilder builder) {
|
||||||
|
Vec3d diff = end.subtract(start);
|
||||||
|
if (diff.x + diff.y + diff.z < 0) {
|
||||||
|
Vec3d temp = start;
|
||||||
|
start = end;
|
||||||
|
end = temp;
|
||||||
|
diff = diff.scale(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3d extension = diff.normalize().scale(lineWidth / 2);
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(diff);
|
||||||
|
Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis();
|
||||||
|
|
||||||
|
start = start.subtract(extension);
|
||||||
|
end = end.add(extension);
|
||||||
|
plane = plane.scale(lineWidth / 2);
|
||||||
|
Vec3d a1 = plane.add(start);
|
||||||
|
Vec3d b1 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a2 = plane.add(start);
|
||||||
|
Vec3d b2 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a3 = plane.add(start);
|
||||||
|
Vec3d b3 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a4 = plane.add(start);
|
||||||
|
Vec3d b4 = plane.add(end);
|
||||||
|
|
||||||
|
putQuad(b4, b3, b2, b1, rgb, alpha, builder);
|
||||||
|
putQuad(a1, a2, a3, a4, rgb, alpha, builder);
|
||||||
|
|
||||||
|
putQuad(a1, b1, b2, a2, rgb, alpha, builder);
|
||||||
|
putQuad(a2, b2, b3, a3, rgb, alpha, builder);
|
||||||
|
putQuad(a3, b3, b4, a4, rgb, alpha, builder);
|
||||||
|
putQuad(a4, b4, b1, a1, rgb, alpha, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset,
|
||||||
|
IVertexBuilder builder) {
|
||||||
|
Vec3d center = VecHelper.getCenterOf(pos);
|
||||||
|
Vec3d offset = new Vec3d(face.getDirectionVec());
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(offset);
|
||||||
|
Axis axis = face.getAxis();
|
||||||
|
|
||||||
|
offset = offset.scale(1 / 2f + scaleOffset);
|
||||||
|
plane = plane.scale(1 / 2f).add(offset);
|
||||||
|
|
||||||
|
int deg = face.getAxisDirection().getOffset() * 90;
|
||||||
|
Vec3d a1 = plane.add(center);
|
||||||
|
plane = VecHelper.rotate(plane, deg, axis);
|
||||||
|
Vec3d a2 = plane.add(center);
|
||||||
|
plane = VecHelper.rotate(plane, deg, axis);
|
||||||
|
Vec3d a3 = plane.add(center);
|
||||||
|
plane = VecHelper.rotate(plane, deg, axis);
|
||||||
|
Vec3d a4 = plane.add(center);
|
||||||
|
|
||||||
|
putQuad(a1, a2, a3, a4, rgb, alpha, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, IVertexBuilder builder) {
|
||||||
|
putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, float maxV,
|
||||||
|
Vec3d rgb, float alpha, IVertexBuilder builder) {
|
||||||
|
putVertex(v1, rgb, minU, minV, alpha, builder);
|
||||||
|
putVertex(v2, rgb, maxU, minV, alpha, builder);
|
||||||
|
putVertex(v3, rgb, maxU, maxV, alpha, builder);
|
||||||
|
putVertex(v4, rgb, minU, maxV, alpha, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, IVertexBuilder builder) {
|
||||||
|
int i = 15 << 20 | 15 << 4;
|
||||||
|
int j = i >> 16 & '\uffff';
|
||||||
|
int k = i & '\uffff';
|
||||||
|
builder.vertex(pos.x, pos.y, pos.z).texture(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha)
|
||||||
|
.light(j, k).endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.simibubi.create.foundation.utility.outliner;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.particle.IParticleRenderType;
|
||||||
|
import net.minecraft.client.particle.Particle;
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class OutlineParticle<O extends Outline> extends Particle {
|
||||||
|
|
||||||
|
protected O outline;
|
||||||
|
|
||||||
|
protected OutlineParticle(O outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) {
|
||||||
|
super(worldIn, xCoordIn, yCoordIn, zCoordIn);
|
||||||
|
this.outline = outline;
|
||||||
|
this.maxAge = 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O extends Outline> OutlineParticle<O> create(O outline) {
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
ClientPlayerEntity player = mc.player;
|
||||||
|
OutlineParticle<O> effect =
|
||||||
|
new OutlineParticle<>(outline, mc.world, player.getX(), player.getY(), player.getZ());
|
||||||
|
mc.particles.addEffect(effect);
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
isExpired = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo renderInfo, float p_225606_3_) {
|
||||||
|
Vec3d view = renderInfo.getProjectedView();
|
||||||
|
// GlStateManager.translated(-view.x, -view.y, -view.z);
|
||||||
|
// TODO
|
||||||
|
// GlStateManager.enableBlend();
|
||||||
|
// getOutline().render(buffer);
|
||||||
|
// GlStateManager.disableBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IParticleRenderType getRenderType() {
|
||||||
|
return IParticleRenderType.CUSTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public O getOutline() {
|
||||||
|
return outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.config.AllConfigs;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
import net.minecraft.crash.ReportedException;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class StructureRenderer {
|
||||||
|
|
||||||
|
protected static LightingWorld lightingWorld;
|
||||||
|
|
||||||
|
public static void renderTileEntities(World world, Vec3d position, Vec3d rotation,
|
||||||
|
Iterable<TileEntity> customRenderTEs, MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||||
|
float pt = Minecraft.getInstance().getRenderPartialTicks();
|
||||||
|
|
||||||
|
if (lightingWorld == null)
|
||||||
|
lightingWorld = new LightingWorld(world);
|
||||||
|
lightingWorld.setWorld(world);
|
||||||
|
lightingWorld.setTransform(position, rotation);
|
||||||
|
|
||||||
|
for (Iterator<TileEntity> iterator = customRenderTEs.iterator(); iterator.hasNext();) {
|
||||||
|
TileEntity tileEntity = iterator.next();
|
||||||
|
if (TileEntityRendererDispatcher.instance.getRenderer(tileEntity) == null) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
BlockPos pos = tileEntity.getPos();
|
||||||
|
if (!tileEntity.hasFastRenderer()) {
|
||||||
|
RenderHelper.enable();
|
||||||
|
int i = WorldRenderer.getLightmapCoordinates(lightingWorld, pos);
|
||||||
|
int j = LightTexture.getBlockLightCoordinates(i);
|
||||||
|
int k = LightTexture.getSkyLightCoordinates(i);
|
||||||
|
RenderSystem.glMultiTexCoord2f(GL13.GL_TEXTURE1, (float) j, (float) k);
|
||||||
|
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderSystem.disableCull();
|
||||||
|
World prevTileWorld = tileEntity.getWorld();
|
||||||
|
tileEntity.setLocation(lightingWorld, pos);
|
||||||
|
TileEntityRendererDispatcher.instance.render(tileEntity, pt, ms, buffer);
|
||||||
|
tileEntity.setLocation(prevTileWorld, pos);
|
||||||
|
RenderSystem.enableCull();
|
||||||
|
|
||||||
|
} catch (ReportedException e) {
|
||||||
|
if (AllConfigs.CLIENT.explainRenderErrors.get()) {
|
||||||
|
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
|
||||||
|
+ " didn't want to render while moved.\n", e);
|
||||||
|
} else {
|
||||||
|
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
|
||||||
|
+ " didn't want to render while moved.\n");
|
||||||
|
}
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LightingWorld extends WrappedWorld {
|
||||||
|
|
||||||
|
private Vec3d offset;
|
||||||
|
private Vec3d rotation;
|
||||||
|
|
||||||
|
public LightingWorld(World world) {
|
||||||
|
super(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWorld(World world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTransform(Vec3d offset, Vec3d rotation) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBaseLightLevel(BlockPos pos, int minLight) {
|
||||||
|
return super.getBaseLightLevel(transformPos(pos), minLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockPos transformPos(BlockPos pos) {
|
||||||
|
Vec3d vec = VecHelper.getCenterOf(pos);
|
||||||
|
vec = VecHelper.rotate(vec, rotation.x, rotation.y, rotation.z);
|
||||||
|
vec = vec.add(offset).subtract(VecHelper.getCenterOf(BlockPos.ZERO));
|
||||||
|
return new BlockPos(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
package com.simibubi.create.foundation.world;
|
package com.simibubi.create.foundation.world;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions;
|
package com.simibubi.create.modules.contraptions;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions.base;
|
package com.simibubi.create.modules.contraptions.base;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.item.ItemDescription.Palette;
|
import com.simibubi.create.foundation.item.ItemDescription.Palette;
|
||||||
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;
|
||||||
|
@ -45,7 +44,10 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||||
return tool == ToolType.AXE || tool == ToolType.PICKAXE;
|
return tool == ToolType.AXE || tool == ToolType.PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRotate
|
@Override
|
||||||
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
|
// onBlockAdded is useless for init, as sometimes the TE gets re-instantiated
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
|
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
|
||||||
|
@ -57,8 +59,6 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTileEntity(BlockState state) {
|
public boolean hasTileEntity(BlockState state) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -72,8 +72,8 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||||
@Override
|
@Override
|
||||||
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
|
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
|
||||||
super.updateNeighbors(stateIn, worldIn, pos, flags);
|
super.updateNeighbors(stateIn, worldIn, pos, flags);
|
||||||
if (worldIn.isRemote())
|
if (worldIn.isRemote())
|
||||||
|
@ -83,8 +83,11 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||||
if (!(tileEntity instanceof KineticTileEntity))
|
if (!(tileEntity instanceof KineticTileEntity))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Remove previous information when block is added
|
||||||
KineticTileEntity kte = (KineticTileEntity) tileEntity;
|
KineticTileEntity kte = (KineticTileEntity) tileEntity;
|
||||||
RotationPropagator.handleAdded(worldIn.getWorld(), pos, kte);
|
kte.warnOfMovement();
|
||||||
|
kte.clearKineticInformation();
|
||||||
|
kte.updateSpeed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override // TODO 1.15 register layer
|
// @Override // TODO 1.15 register layer
|
||||||
|
|
|
@ -41,12 +41,14 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
public @Nullable Long network;
|
public @Nullable Long network;
|
||||||
public @Nullable BlockPos source;
|
public @Nullable BlockPos source;
|
||||||
public boolean networkDirty;
|
public boolean networkDirty;
|
||||||
|
public boolean updateSpeed;
|
||||||
|
|
||||||
protected KineticEffectHandler effects;
|
protected KineticEffectHandler effects;
|
||||||
protected float speed;
|
protected float speed;
|
||||||
protected float capacity;
|
protected float capacity;
|
||||||
protected float stress;
|
protected float stress;
|
||||||
protected boolean overStressed;
|
protected boolean overStressed;
|
||||||
|
protected boolean wasMoved;
|
||||||
|
|
||||||
private int flickerTally;
|
private int flickerTally;
|
||||||
private int networkSize;
|
private int networkSize;
|
||||||
|
@ -57,6 +59,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
public KineticTileEntity(TileEntityType<?> typeIn) {
|
public KineticTileEntity(TileEntityType<?> typeIn) {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
effects = new KineticEffectHandler(this);
|
effects = new KineticEffectHandler(this);
|
||||||
|
updateSpeed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,6 +76,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
if (!world.isRemote && needsSpeedUpdate())
|
||||||
|
attachKinetics();
|
||||||
|
|
||||||
super.tick();
|
super.tick();
|
||||||
effects.tick();
|
effects.tick();
|
||||||
|
|
||||||
|
@ -179,6 +185,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
compound.putFloat("Speed", speed);
|
compound.putFloat("Speed", speed);
|
||||||
|
|
||||||
|
if (needsSpeedUpdate())
|
||||||
|
compound.putBoolean("NeedsSpeedUpdate", true);
|
||||||
|
|
||||||
if (hasSource())
|
if (hasSource())
|
||||||
compound.put("Source", NBTUtil.writeBlockPos(source));
|
compound.put("Source", NBTUtil.writeBlockPos(source));
|
||||||
|
|
||||||
|
@ -200,16 +209,21 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean needsSpeedUpdate() {
|
||||||
|
return updateSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
|
clearKineticInformation();
|
||||||
|
|
||||||
|
// DO NOT READ kinetic information when placed after movement
|
||||||
|
if (wasMoved) {
|
||||||
|
super.read(compound);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
speed = compound.getFloat("Speed");
|
speed = compound.getFloat("Speed");
|
||||||
source = null;
|
|
||||||
network = null;
|
|
||||||
overStressed = false;
|
|
||||||
stress = 0;
|
|
||||||
capacity = 0;
|
|
||||||
lastStressApplied = 0;
|
|
||||||
lastCapacityProvided = 0;
|
|
||||||
|
|
||||||
if (compound.contains("Source"))
|
if (compound.contains("Source"))
|
||||||
source = NBTUtil.readBlockPos(compound.getCompound("Source"));
|
source = NBTUtil.readBlockPos(compound.getCompound("Source"));
|
||||||
|
@ -313,6 +327,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachKinetics() {
|
public void attachKinetics() {
|
||||||
|
updateSpeed = false;
|
||||||
RotationPropagator.handleAdded(world, pos, this);
|
RotationPropagator.handleAdded(world, pos, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +429,21 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearKineticInformation() {
|
||||||
|
speed = 0;
|
||||||
|
source = null;
|
||||||
|
network = null;
|
||||||
|
overStressed = false;
|
||||||
|
stress = 0;
|
||||||
|
capacity = 0;
|
||||||
|
lastStressApplied = 0;
|
||||||
|
lastCapacityProvided = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void warnOfMovement() {
|
||||||
|
wasMoved = true;
|
||||||
|
}
|
||||||
|
|
||||||
public int getFlickerScore() {
|
public int getFlickerScore() {
|
||||||
return flickerTally;
|
return flickerTally;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.actors;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.AllShapes;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.HorizontalBlock;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorldReader;
|
||||||
|
|
||||||
|
public abstract class AttachedActorBlock extends HorizontalBlock implements IPortableBlock {
|
||||||
|
|
||||||
|
public AttachedActorBlock() {
|
||||||
|
super(Properties.from(Blocks.IRON_BLOCK));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||||
|
Direction direction = state.get(HORIZONTAL_FACING);
|
||||||
|
return AllShapes.HARVESTER_BASE.get(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(HORIZONTAL_FACING);
|
||||||
|
super.fillStateContainer(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||||
|
Direction direction = state.get(HORIZONTAL_FACING);
|
||||||
|
BlockPos offset = pos.offset(direction.getOpposite());
|
||||||
|
return Block.hasSolidSide(worldIn.getBlockState(offset), worldIn, offset, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||||
|
Direction facing;
|
||||||
|
if (context.getFace().getAxis().isVertical())
|
||||||
|
facing = context.getPlacementHorizontalFacing().getOpposite();
|
||||||
|
else {
|
||||||
|
BlockState blockState =
|
||||||
|
context.getWorld().getBlockState(context.getPos().offset(context.getFace().getOpposite()));
|
||||||
|
if (blockState.getBlock() instanceof AttachedActorBlock)
|
||||||
|
facing = blockState.get(HORIZONTAL_FACING);
|
||||||
|
else
|
||||||
|
facing = context.getFace();
|
||||||
|
}
|
||||||
|
return getDefaultState().with(HORIZONTAL_FACING, facing);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,9 +6,11 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.FallingBlock;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
|
@ -32,30 +34,10 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
World world = context.world;
|
World world = context.world;
|
||||||
BlockState stateVisited = world.getBlockState(pos);
|
BlockState stateVisited = world.getBlockState(pos);
|
||||||
|
|
||||||
|
if (!stateVisited.isNormalCube(world, pos))
|
||||||
|
damageEntities(context, pos, world);
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (stateVisited.getCollisionShape(world, pos).isEmpty()) {
|
|
||||||
DamageSource damageSource = getDamageSource();
|
|
||||||
if (damageSource == null)
|
|
||||||
return;
|
|
||||||
for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
|
|
||||||
|
|
||||||
if (entity instanceof ItemEntity)
|
|
||||||
return;
|
|
||||||
if (entity instanceof ContraptionEntity)
|
|
||||||
return;
|
|
||||||
if (entity instanceof AbstractMinecartEntity)
|
|
||||||
for (Entity passenger : entity.getRecursivePassengers())
|
|
||||||
if (passenger instanceof ContraptionEntity
|
|
||||||
&& ((ContraptionEntity) passenger).getContraption() == context.contraption)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
|
|
||||||
entity.attackEntityFrom(damageSource, damage);
|
|
||||||
entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3)));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!canBreak(world, pos, stateVisited))
|
if (!canBreak(world, pos, stateVisited))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -63,10 +45,44 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
context.stall = true;
|
context.stall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void damageEntities(MovementContext context, BlockPos pos, World world) {
|
||||||
|
DamageSource damageSource = getDamageSource();
|
||||||
|
if (damageSource == null && !throwsEntities())
|
||||||
|
return;
|
||||||
|
Entities: for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
|
||||||
|
if (entity instanceof ItemEntity)
|
||||||
|
continue;
|
||||||
|
if (entity instanceof ContraptionEntity)
|
||||||
|
continue;
|
||||||
|
if (entity instanceof AbstractMinecartEntity)
|
||||||
|
for (Entity passenger : entity.getRecursivePassengers())
|
||||||
|
if (passenger instanceof ContraptionEntity
|
||||||
|
&& ((ContraptionEntity) passenger).getContraption() == context.contraption)
|
||||||
|
continue Entities;
|
||||||
|
|
||||||
|
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
|
||||||
|
if (damageSource != null && !world.isRemote)
|
||||||
|
entity.attackEntityFrom(damageSource, damage);
|
||||||
|
if (throwsEntities() && (world.isRemote == (entity instanceof PlayerEntity))) {
|
||||||
|
Vec3d motionBoost = context.motion.add(0, context.motion.length() / 4f, 0);
|
||||||
|
int maxBoost = 4;
|
||||||
|
if (motionBoost.length() > maxBoost) {
|
||||||
|
motionBoost = motionBoost.subtract(motionBoost.normalize().scale(motionBoost.length() - maxBoost));
|
||||||
|
}
|
||||||
|
entity.setMotion(entity.getMotion().add(motionBoost));
|
||||||
|
entity.velocityChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected DamageSource getDamageSource() {
|
protected DamageSource getDamageSource() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean throwsEntities() {
|
||||||
|
return getDamageSource() != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopMoving(MovementContext context) {
|
public void stopMoving(MovementContext context) {
|
||||||
CompoundNBT data = context.data;
|
CompoundNBT data = context.data;
|
||||||
|
@ -89,6 +105,27 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(MovementContext context) {
|
public void tick(MovementContext context) {
|
||||||
|
tickBreaker(context);
|
||||||
|
|
||||||
|
CompoundNBT data = context.data;
|
||||||
|
if (!data.contains("WaitingTicks"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int waitingTicks = data.getInt("WaitingTicks");
|
||||||
|
if (waitingTicks-- > 0) {
|
||||||
|
data.putInt("WaitingTicks", waitingTicks);
|
||||||
|
context.stall = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos pos = NBTUtil.readBlockPos(data.getCompound("LastPos"));
|
||||||
|
data.remove("WaitingTicks");
|
||||||
|
data.remove("LastPos");
|
||||||
|
context.stall = false;
|
||||||
|
visitNewPosition(context, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tickBreaker(MovementContext context) {
|
||||||
CompoundNBT data = context.data;
|
CompoundNBT data = context.data;
|
||||||
if (context.world.isRemote)
|
if (context.world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
@ -128,14 +165,24 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
||||||
|
|
||||||
if (destroyProgress >= 10) {
|
if (destroyProgress >= 10) {
|
||||||
BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack));
|
|
||||||
onBlockBroken(context, breakingPos);
|
|
||||||
ticksUntilNextProgress = -1;
|
|
||||||
world.sendBlockBreakProgress(id, breakingPos, -1);
|
world.sendBlockBreakProgress(id, breakingPos, -1);
|
||||||
|
|
||||||
|
// break falling blocks from top to bottom
|
||||||
|
BlockPos ogPos = breakingPos;
|
||||||
|
BlockState stateAbove = world.getBlockState(breakingPos.up());
|
||||||
|
while (stateAbove.getBlock() instanceof FallingBlock) {
|
||||||
|
breakingPos = breakingPos.up();
|
||||||
|
stateAbove = world.getBlockState(breakingPos.up());
|
||||||
|
}
|
||||||
|
stateToBreak = world.getBlockState(breakingPos);
|
||||||
|
|
||||||
|
context.stall = false;
|
||||||
|
BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack));
|
||||||
|
onBlockBroken(context, ogPos, stateToBreak);
|
||||||
|
ticksUntilNextProgress = -1;
|
||||||
data.remove("Progress");
|
data.remove("Progress");
|
||||||
data.remove("TicksUntilNextProgress");
|
data.remove("TicksUntilNextProgress");
|
||||||
data.remove("BreakingPos");
|
data.remove("BreakingPos");
|
||||||
context.stall = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +197,15 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
|
||||||
return BlockBreakingKineticTileEntity.isBreakable(state, blockHardness);
|
return BlockBreakingKineticTileEntity.isBreakable(state, blockHardness);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onBlockBroken(MovementContext context, BlockPos pos) {
|
protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) {
|
||||||
|
// Check for falling blocks
|
||||||
|
if (!(brokenState.getBlock() instanceof FallingBlock))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CompoundNBT data = context.data;
|
||||||
|
data.putInt("WaitingTicks", 10);
|
||||||
|
data.put("LastPos", NBTUtil.writeBlockPos(pos));
|
||||||
|
context.stall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,11 @@ 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.components.contraptions.MovementContext;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@ -33,4 +36,9 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
|
||||||
return DrillBlock.damageSourceDrill;
|
return DrillBlock.damageSourceDrill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||||
|
return super.canBreak(world, breakingPos, state) && !state.getCollisionShape(world, breakingPos).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,16 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.actors;
|
package com.simibubi.create.modules.contraptions.components.actors;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.foundation.utility.AllShapes;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.HorizontalBlock;
|
|
||||||
import net.minecraft.block.material.PushReaction;
|
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
|
||||||
import net.minecraft.state.StateContainer.Builder;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorldReader;
|
|
||||||
|
|
||||||
public class HarvesterBlock extends HorizontalBlock implements IPortableBlock {
|
public class HarvesterBlock extends AttachedActorBlock implements IPortableBlock {
|
||||||
|
|
||||||
public static MovementBehaviour MOVEMENT = new HarvesterMovementBehaviour();
|
public static MovementBehaviour MOVEMENT = new HarvesterMovementBehaviour();
|
||||||
|
|
||||||
public HarvesterBlock() {
|
|
||||||
super(Properties.from(Blocks.IRON_BLOCK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTileEntity(BlockState state) {
|
public boolean hasTileEntity(BlockState state) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -38,51 +21,11 @@ public class HarvesterBlock extends HorizontalBlock implements IPortableBlock {
|
||||||
return new HarvesterTileEntity();
|
return new HarvesterTileEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PushReaction getPushReaction(BlockState state) {
|
|
||||||
return PushReaction.PUSH_ONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
|
||||||
Direction direction = state.get(HORIZONTAL_FACING);
|
|
||||||
return AllShapes.HARVESTER_BASE.get(direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(HORIZONTAL_FACING);
|
|
||||||
super.fillStateContainer(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override // TOOD 1.15 register layer
|
// @Override // TOOD 1.15 register layer
|
||||||
// public BlockRenderLayer getRenderLayer() {
|
// public BlockRenderLayer getRenderLayer() {
|
||||||
// return BlockRenderLayer.CUTOUT;
|
// return BlockRenderLayer.CUTOUT;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
|
||||||
Direction direction = state.get(HORIZONTAL_FACING);
|
|
||||||
BlockPos offset = pos.offset(direction.getOpposite());
|
|
||||||
return Block.hasSolidSide(worldIn.getBlockState(offset), worldIn, offset, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
|
||||||
Direction facing;
|
|
||||||
if (context.getFace().getAxis().isVertical())
|
|
||||||
facing = context.getPlacementHorizontalFacing().getOpposite();
|
|
||||||
else {
|
|
||||||
BlockState blockState =
|
|
||||||
context.getWorld().getBlockState(context.getPos().offset(context.getFace().getOpposite()));
|
|
||||||
if (AllBlocks.HARVESTER.typeOf(blockState))
|
|
||||||
facing = blockState.get(HORIZONTAL_FACING);
|
|
||||||
else
|
|
||||||
facing = context.getFace();
|
|
||||||
}
|
|
||||||
return getDefaultState().with(HORIZONTAL_FACING, facing);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MovementBehaviour getMovementBehaviour() {
|
public MovementBehaviour getMovementBehaviour() {
|
||||||
return MOVEMENT;
|
return MOVEMENT;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec3d getActiveAreaOffset(MovementContext context) {
|
public Vec3d getActiveAreaOffset(MovementContext context) {
|
||||||
return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.5);
|
return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.45);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.actors;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||||
|
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
|
|
||||||
|
public class PloughBlock extends AttachedActorBlock {
|
||||||
|
|
||||||
|
public static MovementBehaviour MOVEMENT = new PloughMovementBehaviour();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MovementBehaviour getMovementBehaviour() {
|
||||||
|
return MOVEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OnHoeUse event takes a player, so we better not pass null
|
||||||
|
*/
|
||||||
|
static class PloughFakePlayer extends FakePlayer {
|
||||||
|
|
||||||
|
public static final GameProfile PLOUGH_PROFILE =
|
||||||
|
new GameProfile(UUID.fromString("9e2faded-eeee-4ec2-c314-dad129ae971d"), "Plough");
|
||||||
|
|
||||||
|
public PloughFakePlayer(ServerWorld world) {
|
||||||
|
super(world, PLOUGH_PROFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.actors;
|
||||||
|
|
||||||
|
import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.actors.PloughBlock.PloughFakePlayer;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
|
import net.minecraft.util.math.RayTraceResult.Type;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
|
||||||
|
public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive(MovementContext context) {
|
||||||
|
return !VecHelper.isVecPointingTowards(context.relativeMotion,
|
||||||
|
context.state.get(HORIZONTAL_FACING).getOpposite());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewPosition(MovementContext context, BlockPos pos) {
|
||||||
|
super.visitNewPosition(context, pos);
|
||||||
|
World world = context.world;
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
BlockPos below = pos.down();
|
||||||
|
if (!world.isBlockPresent(below))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vec3d vec = VecHelper.getCenterOf(pos);
|
||||||
|
PloughFakePlayer player = getPlayer(context);
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BlockRayTraceResult ray = world
|
||||||
|
.rayTraceBlocks(new RayTraceContext(vec, vec.add(0, -1, 0), BlockMode.OUTLINE, FluidMode.NONE, player));
|
||||||
|
if (ray == null || ray.getType() != Type.BLOCK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemUseContext ctx = new ItemUseContext(player, Hand.MAIN_HAND, ray);
|
||||||
|
new ItemStack(Items.DIAMOND_HOE).onItemUse(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3d getActiveAreaOffset(MovementContext context) {
|
||||||
|
return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean throwsEntities() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||||
|
return state.getCollisionShape(world, breakingPos).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopMoving(MovementContext context) {
|
||||||
|
super.stopMoving(context);
|
||||||
|
if (context.temporaryData instanceof PloughFakePlayer)
|
||||||
|
((PloughFakePlayer) context.temporaryData).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PloughFakePlayer getPlayer(MovementContext context) {
|
||||||
|
if (!(context.temporaryData instanceof PloughFakePlayer) && context.world instanceof ServerWorld) {
|
||||||
|
PloughFakePlayer player = new PloughFakePlayer((ServerWorld) context.world);
|
||||||
|
player.setHeldItem(Hand.MAIN_HAND, new ItemStack(Items.DIAMOND_HOE));
|
||||||
|
context.temporaryData = player;
|
||||||
|
}
|
||||||
|
return (PloughFakePlayer) context.temporaryData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.TreeCutter.Tree;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||||
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.saw.SawTileEntity;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
@ -31,12 +32,13 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||||
return super.canBreak(world, breakingPos, state)
|
return super.canBreak(world, breakingPos, state) && SawTileEntity.isSawable(state);
|
||||||
&& (state.isIn(BlockTags.LOGS) || state.isIn(BlockTags.LEAVES));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBlockBroken(MovementContext context, BlockPos pos) {
|
protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) {
|
||||||
|
if (brokenState.isIn(BlockTags.LEAVES))
|
||||||
|
return;
|
||||||
Tree tree = TreeCutter.cutTree(context.world, pos);
|
Tree tree = TreeCutter.cutTree(context.world, pos);
|
||||||
if (tree != null) {
|
if (tree != null) {
|
||||||
for (BlockPos log : tree.logs)
|
for (BlockPos log : tree.logs)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.actors.AttachedActorBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
|
||||||
|
@ -11,6 +12,8 @@ import com.simibubi.create.modules.contraptions.components.contraptions.chassis.
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
||||||
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
|
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
|
||||||
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
|
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
|
||||||
|
@ -82,7 +85,7 @@ public class BlockMovementTraits {
|
||||||
if (block instanceof PulleyBlock) {
|
if (block instanceof PulleyBlock) {
|
||||||
TileEntity te = world.getTileEntity(pos);
|
TileEntity te = world.getTileEntity(pos);
|
||||||
if (te instanceof PulleyTileEntity)
|
if (te instanceof PulleyTileEntity)
|
||||||
return !((PulleyTileEntity) te).running && ((PulleyTileEntity) te).offset == 0;
|
return !((PulleyTileEntity) te).running;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AllBlocks.BELT.typeOf(blockState))
|
if (AllBlocks.BELT.typeOf(blockState))
|
||||||
|
@ -126,6 +129,10 @@ public class BlockMovementTraits {
|
||||||
return true;
|
return true;
|
||||||
if (block instanceof RedstoneLinkBlock)
|
if (block instanceof RedstoneLinkBlock)
|
||||||
return true;
|
return true;
|
||||||
|
if (block instanceof RopeBlock)
|
||||||
|
return true;
|
||||||
|
if (block instanceof MagnetBlock)
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +176,7 @@ public class BlockMovementTraits {
|
||||||
return direction == (state.get(BlockStateProperties.HANGING) ? Direction.UP : Direction.DOWN);
|
return direction == (state.get(BlockStateProperties.HANGING) ? Direction.UP : Direction.DOWN);
|
||||||
if (block instanceof AbstractRailBlock)
|
if (block instanceof AbstractRailBlock)
|
||||||
return direction == Direction.DOWN;
|
return direction == Direction.DOWN;
|
||||||
if (block instanceof HarvesterBlock)
|
if (block instanceof AttachedActorBlock)
|
||||||
return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite();
|
return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -185,8 +192,10 @@ public class BlockMovementTraits {
|
||||||
return state.get(BlockStateProperties.FACING) == facing;
|
return state.get(BlockStateProperties.FACING) == facing;
|
||||||
if (AllBlocks.PORTABLE_STORAGE_INTERFACE.typeOf(state))
|
if (AllBlocks.PORTABLE_STORAGE_INTERFACE.typeOf(state))
|
||||||
return state.get(PortableStorageInterfaceBlock.FACING) == facing;
|
return state.get(PortableStorageInterfaceBlock.FACING) == facing;
|
||||||
if (AllBlocks.HARVESTER.typeOf(state))
|
if (state.getBlock() instanceof AttachedActorBlock)
|
||||||
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
|
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
|
||||||
|
if (AllBlocks.ROPE_PULLEY.typeOf(state))
|
||||||
|
return facing == Direction.DOWN;
|
||||||
return isBrittle(state);
|
return isBrittle(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,18 +10,19 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
|
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
|
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllKeys;
|
import com.simibubi.create.AllKeys;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.outliner.BlockClusterOutline;
|
||||||
|
import com.simibubi.create.foundation.utility.outliner.Outline;
|
||||||
|
import com.simibubi.create.foundation.utility.outliner.OutlineParticle;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -35,13 +36,15 @@ public class ChassisRangeDisplay {
|
||||||
private static GroupEntry lastHoveredGroup = null;
|
private static GroupEntry lastHoveredGroup = null;
|
||||||
|
|
||||||
private static class Entry {
|
private static class Entry {
|
||||||
Set<BlockPos> includedPositions;
|
BlockClusterOutline outline;
|
||||||
|
OutlineParticle<Outline> particle;
|
||||||
ChassisTileEntity te;
|
ChassisTileEntity te;
|
||||||
int timer;
|
int timer;
|
||||||
|
|
||||||
public Entry(ChassisTileEntity te) {
|
public Entry(ChassisTileEntity te) {
|
||||||
this.te = te;
|
this.te = te;
|
||||||
includedPositions = createSelection(te);
|
outline = new BlockClusterOutline(createSelection(te));
|
||||||
|
particle = OutlineParticle.create(outline);
|
||||||
timer = DISPLAY_TIME;
|
timer = DISPLAY_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +88,19 @@ public class ChassisRangeDisplay {
|
||||||
World world = Minecraft.getInstance().world;
|
World world = Minecraft.getInstance().world;
|
||||||
boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand());
|
boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand());
|
||||||
|
|
||||||
for (Iterator<BlockPos> iterator = entries.keySet().iterator(); iterator.hasNext();)
|
for (Iterator<BlockPos> iterator = entries.keySet().iterator(); iterator.hasNext();) {
|
||||||
if (tickEntry(entries.get(iterator.next()), hasWrench))
|
Entry entry = entries.get(iterator.next());
|
||||||
|
if (tickEntry(entry, hasWrench)) {
|
||||||
|
entry.particle.remove();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Iterator<GroupEntry> iterator = groupEntries.iterator(); iterator.hasNext();) {
|
for (Iterator<GroupEntry> iterator = groupEntries.iterator(); iterator.hasNext();) {
|
||||||
GroupEntry group = iterator.next();
|
GroupEntry group = iterator.next();
|
||||||
if (tickEntry(group, hasWrench)) {
|
if (tickEntry(group, hasWrench)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
group.particle.remove();
|
||||||
if (group == lastHoveredGroup)
|
if (group == lastHoveredGroup)
|
||||||
lastHoveredGroup = null;
|
lastHoveredGroup = null;
|
||||||
}
|
}
|
||||||
|
@ -118,8 +126,11 @@ public class ChassisRangeDisplay {
|
||||||
if (ctrl) {
|
if (ctrl) {
|
||||||
GroupEntry existingGroupForPos = getExistingGroupForPos(pos);
|
GroupEntry existingGroupForPos = getExistingGroupForPos(pos);
|
||||||
if (existingGroupForPos != null) {
|
if (existingGroupForPos != null) {
|
||||||
for (ChassisTileEntity included : existingGroupForPos.includedTEs)
|
for (ChassisTileEntity included : existingGroupForPos.includedTEs) {
|
||||||
entries.remove(included.getPos());
|
Entry removed = entries.remove(included.getPos());
|
||||||
|
if (removed != null)
|
||||||
|
removed.particle.remove();
|
||||||
|
}
|
||||||
existingGroupForPos.timer = DISPLAY_TIME;
|
existingGroupForPos.timer = DISPLAY_TIME;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -167,13 +178,19 @@ public class ChassisRangeDisplay {
|
||||||
public static void display(ChassisTileEntity chassis) {
|
public static void display(ChassisTileEntity chassis) {
|
||||||
deselect();
|
deselect();
|
||||||
if (AllKeys.ctrlDown()) {
|
if (AllKeys.ctrlDown()) {
|
||||||
|
groupEntries.forEach(e -> e.particle.remove());
|
||||||
groupEntries.clear();
|
groupEntries.clear();
|
||||||
GroupEntry hoveredGroup = new GroupEntry(chassis);
|
GroupEntry hoveredGroup = new GroupEntry(chassis);
|
||||||
for (ChassisTileEntity included : hoveredGroup.includedTEs)
|
for (ChassisTileEntity included : hoveredGroup.includedTEs) {
|
||||||
entries.remove(included.getPos());
|
Entry remove = entries.remove(included.getPos());
|
||||||
|
if (remove != null)
|
||||||
|
remove.particle.remove();
|
||||||
|
}
|
||||||
groupEntries.add(hoveredGroup);
|
groupEntries.add(hoveredGroup);
|
||||||
} else {
|
} else {
|
||||||
entries.put(chassis.getPos(), new Entry(chassis));
|
Entry old = entries.put(chassis.getPos(), new Entry(chassis));
|
||||||
|
if (old != null)
|
||||||
|
old.particle.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,17 +213,23 @@ public class ChassisRangeDisplay {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderPositions(Entry entry, float partialTicks) {
|
public static void renderPositions(Entry entry, float partialTicks) {
|
||||||
TessellatorHelper.begin();
|
// GlStateManager.pushMatrix();
|
||||||
BlockPos size = new BlockPos(1, 1, 1);
|
// RenderHelper.disableStandardItemLighting();
|
||||||
|
// GlStateManager.normal3f(0.0F, 1.0F, 0.0F);
|
||||||
|
// GlStateManager.color4f(1, 1, 1, 1);
|
||||||
|
// GlStateManager.enableTexture();
|
||||||
|
// GlStateManager.depthMask(false);
|
||||||
|
// GlStateManager.enableBlend();
|
||||||
|
// GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
|
//
|
||||||
float timer = entry.timer - partialTicks;
|
float timer = entry.timer - partialTicks;
|
||||||
float alpha = timer > 20 ? .5f : timer / 40f;
|
float alpha = timer > 20 ? 1 : timer / 20f;
|
||||||
RenderSystem.color4f(1, .7f, 0, alpha);
|
entry.outline.setAlpha(alpha);
|
||||||
Set<BlockPos> includedPositions = entry.includedPositions;
|
// entry.outline.render(Tessellator.getInstance().getBuffer());
|
||||||
GlStateManager.depthMask(false);
|
//
|
||||||
for (BlockPos pos : includedPositions)
|
// GlStateManager.disableBlend();
|
||||||
TessellatorHelper.cube(Tessellator.getInstance().getBuffer(), pos, size, 1 / 16f - 1 / 64f, true, false);
|
// GlStateManager.depthMask(true);
|
||||||
TessellatorHelper.draw();
|
// GlStateManager.popMatrix();
|
||||||
GlStateManager.depthMask(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GroupEntry getExistingGroupForPos(BlockPos pos) {
|
private static GroupEntry getExistingGroupForPos(BlockPos pos) {
|
||||||
|
|
|
@ -25,14 +25,19 @@ import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueHandler;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
||||||
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
|
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractButtonBlock;
|
import net.minecraft.block.AbstractButtonBlock;
|
||||||
|
@ -54,6 +59,7 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Direction.AxisDirection;
|
import net.minecraft.util.Direction.AxisDirection;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -71,6 +77,7 @@ public abstract class Contraption {
|
||||||
public List<MutablePair<BlockInfo, MovementContext>> actors;
|
public List<MutablePair<BlockInfo, MovementContext>> actors;
|
||||||
public CombinedInvWrapper inventory;
|
public CombinedInvWrapper inventory;
|
||||||
public List<TileEntity> customRenderTEs;
|
public List<TileEntity> customRenderTEs;
|
||||||
|
public Set<Pair<BlockPos, Direction>> superglue;
|
||||||
|
|
||||||
public AxisAlignedBB bounds;
|
public AxisAlignedBB bounds;
|
||||||
public boolean stalled;
|
public boolean stalled;
|
||||||
|
@ -80,13 +87,16 @@ public abstract class Contraption {
|
||||||
protected BlockPos anchor;
|
protected BlockPos anchor;
|
||||||
|
|
||||||
List<BlockPos> renderOrder;
|
List<BlockPos> renderOrder;
|
||||||
|
protected List<SuperGlueEntity> glueToRemove;
|
||||||
|
|
||||||
public Contraption() {
|
public Contraption() {
|
||||||
blocks = new HashMap<>();
|
blocks = new HashMap<>();
|
||||||
storage = new HashMap<>();
|
storage = new HashMap<>();
|
||||||
actors = new ArrayList<>();
|
actors = new ArrayList<>();
|
||||||
|
superglue = new HashSet<>();
|
||||||
renderOrder = new ArrayList<>();
|
renderOrder = new ArrayList<>();
|
||||||
customRenderTEs = new ArrayList<>();
|
customRenderTEs = new ArrayList<>();
|
||||||
|
glueToRemove = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
|
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
|
||||||
|
@ -118,7 +128,8 @@ public abstract class Contraption {
|
||||||
if (bounds == null)
|
if (bounds == null)
|
||||||
bounds = new AxisAlignedBB(BlockPos.ZERO);
|
bounds = new AxisAlignedBB(BlockPos.ZERO);
|
||||||
|
|
||||||
frontier.add(pos);
|
if (!BlockMovementTraits.isBrittle(world.getBlockState(pos)))
|
||||||
|
frontier.add(pos);
|
||||||
if (!addToInitialFrontier(world, pos, forcedDirection, frontier))
|
if (!addToInitialFrontier(world, pos, forcedDirection, frontier))
|
||||||
return false;
|
return false;
|
||||||
for (int limit = 100000; limit > 0; limit--) {
|
for (int limit = 100000; limit > 0; limit--) {
|
||||||
|
@ -148,6 +159,8 @@ public abstract class Contraption {
|
||||||
|
|
||||||
if (!world.isBlockPresent(pos))
|
if (!world.isBlockPresent(pos))
|
||||||
return false;
|
return false;
|
||||||
|
if (isAnchoringBlockAt(pos))
|
||||||
|
return true;
|
||||||
if (!BlockMovementTraits.movementNecessary(world, pos))
|
if (!BlockMovementTraits.movementNecessary(world, pos))
|
||||||
return true;
|
return true;
|
||||||
if (!BlockMovementTraits.movementAllowed(world, pos))
|
if (!BlockMovementTraits.movementAllowed(world, pos))
|
||||||
|
@ -155,6 +168,7 @@ public abstract class Contraption {
|
||||||
BlockState state = world.getBlockState(pos);
|
BlockState state = world.getBlockState(pos);
|
||||||
if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited))
|
if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (AllBlocks.FLEXCRATE.typeOf(state))
|
if (AllBlocks.FLEXCRATE.typeOf(state))
|
||||||
FlexcrateBlock.splitCrate(world, pos);
|
FlexcrateBlock.splitCrate(world, pos);
|
||||||
if (AllBlocks.BELT.typeOf(state)) {
|
if (AllBlocks.BELT.typeOf(state)) {
|
||||||
|
@ -166,6 +180,26 @@ public abstract class Contraption {
|
||||||
frontier.add(prevPos);
|
frontier.add(prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pulleys drag their rope and their attached structure
|
||||||
|
if (state.getBlock() instanceof PulleyBlock) {
|
||||||
|
int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get();
|
||||||
|
BlockPos ropePos = pos;
|
||||||
|
while (limit-- >= 0) {
|
||||||
|
ropePos = ropePos.down();
|
||||||
|
if (!world.isBlockPresent(ropePos))
|
||||||
|
break;
|
||||||
|
BlockState ropeState = world.getBlockState(ropePos);
|
||||||
|
Block block = ropeState.getBlock();
|
||||||
|
if (!(block instanceof RopeBlock) && !(block instanceof MagnetBlock)) {
|
||||||
|
if (!visited.contains(ropePos))
|
||||||
|
frontier.add(ropePos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
add(ropePos, capture(world, ropePos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pistons drag their attaches poles and extension
|
||||||
if (state.getBlock() instanceof MechanicalPistonBlock) {
|
if (state.getBlock() instanceof MechanicalPistonBlock) {
|
||||||
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
|
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
|
||||||
Direction direction = state.get(MechanicalPistonBlock.FACING);
|
Direction direction = state.get(MechanicalPistonBlock.FACING);
|
||||||
|
@ -208,12 +242,16 @@ public abstract class Contraption {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doors try to stay whole
|
||||||
if (state.getBlock() instanceof DoorBlock) {
|
if (state.getBlock() instanceof DoorBlock) {
|
||||||
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
|
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
|
||||||
if (!visited.contains(otherPartPos))
|
if (!visited.contains(otherPartPos))
|
||||||
frontier.add(otherPartPos);
|
frontier.add(otherPartPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
|
||||||
|
|
||||||
|
// Slime blocks drag adjacent blocks if possible
|
||||||
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
|
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
|
||||||
for (Direction offset : Direction.values()) {
|
for (Direction offset : Direction.values()) {
|
||||||
BlockPos offsetPos = pos.offset(offset);
|
BlockPos offsetPos = pos.offset(offset);
|
||||||
|
@ -225,14 +263,24 @@ public abstract class Contraption {
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!visited.contains(offsetPos)
|
|
||||||
&& (isSlimeBlock || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite())))
|
boolean wasVisited = visited.contains(offsetPos);
|
||||||
|
boolean faceHasGlue = superglue.containsKey(offset);
|
||||||
|
boolean blockAttachedTowardsFace =
|
||||||
|
BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite());
|
||||||
|
boolean brittle = BlockMovementTraits.isBrittle(blockState);
|
||||||
|
|
||||||
|
if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue))
|
||||||
frontier.add(offsetPos);
|
frontier.add(offsetPos);
|
||||||
|
|
||||||
|
if (faceHasGlue)
|
||||||
|
addGlue(superglue.get(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
add(pos, capture(world, pos));
|
add(pos, capture(world, pos));
|
||||||
if (blocks.size() > AllConfigs.SERVER.kinetics.maxBlocksMoved.get())
|
if (blocks.size() > AllConfigs.SERVER.kinetics.maxBlocksMoved.get())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +343,14 @@ public abstract class Contraption {
|
||||||
return compoundnbt;
|
return compoundnbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addGlue(SuperGlueEntity entity) {
|
||||||
|
BlockPos pos = entity.getHangingPosition();
|
||||||
|
Direction direction = entity.getFacingDirection();
|
||||||
|
BlockPos localPos = pos.subtract(anchor);
|
||||||
|
this.superglue.add(Pair.of(localPos, direction));
|
||||||
|
glueToRemove.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> pair) {
|
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> pair) {
|
||||||
BlockInfo captured = pair.getKey();
|
BlockInfo captured = pair.getKey();
|
||||||
BlockPos localPos = pos.subtract(anchor);
|
BlockPos localPos = pos.subtract(anchor);
|
||||||
|
@ -371,6 +427,13 @@ public abstract class Contraption {
|
||||||
getActors().add(MutablePair.of(info, context));
|
getActors().add(MutablePair.of(info, context));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
superglue.clear();
|
||||||
|
nbt.getList("Superglue", 10).forEach(c -> {
|
||||||
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
|
superglue.add(Pair.of(NBTUtil.readBlockPos(comp.getCompound("Pos")),
|
||||||
|
Direction.byIndex(comp.getByte("Direction"))));
|
||||||
|
});
|
||||||
|
|
||||||
storage.clear();
|
storage.clear();
|
||||||
nbt.getList("Storage", 10).forEach(c -> {
|
nbt.getList("Storage", 10).forEach(c -> {
|
||||||
CompoundNBT comp = (CompoundNBT) c;
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
|
@ -409,6 +472,14 @@ public abstract class Contraption {
|
||||||
actorsNBT.add(compound);
|
actorsNBT.add(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListNBT superglueNBT = new ListNBT();
|
||||||
|
for (Pair<BlockPos, Direction> glueEntry : superglue) {
|
||||||
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
c.put("Pos", NBTUtil.writeBlockPos(glueEntry.getKey()));
|
||||||
|
c.putByte("Direction", (byte) glueEntry.getValue().getIndex());
|
||||||
|
superglueNBT.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
ListNBT storageNBT = new ListNBT();
|
ListNBT storageNBT = new ListNBT();
|
||||||
for (BlockPos pos : storage.keySet()) {
|
for (BlockPos pos : storage.keySet()) {
|
||||||
CompoundNBT c = new CompoundNBT();
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
@ -422,6 +493,7 @@ public abstract class Contraption {
|
||||||
|
|
||||||
nbt.put("Blocks", blocksNBT);
|
nbt.put("Blocks", blocksNBT);
|
||||||
nbt.put("Actors", actorsNBT);
|
nbt.put("Actors", actorsNBT);
|
||||||
|
nbt.put("Superglue", superglueNBT);
|
||||||
nbt.put("Storage", storageNBT);
|
nbt.put("Storage", storageNBT);
|
||||||
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
|
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||||
nbt.putBoolean("Stalled", stalled);
|
nbt.putBoolean("Stalled", stalled);
|
||||||
|
@ -435,11 +507,7 @@ public abstract class Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFrozen() {
|
public static boolean isFrozen() {
|
||||||
return AllConfigs.SERVER.control.freezePistonConstructs.get();
|
return AllConfigs.SERVER.control.freezeContraptions.get();
|
||||||
}
|
|
||||||
|
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
|
||||||
disassemble(world, offset, rotation, (pos, state) -> false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
||||||
|
@ -448,6 +516,8 @@ public abstract class Contraption {
|
||||||
|
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
||||||
storage.values().forEach(MountedStorage::empty);
|
storage.values().forEach(MountedStorage::empty);
|
||||||
|
glueToRemove.forEach(SuperGlueEntity::remove);
|
||||||
|
|
||||||
for (boolean brittles : Iterate.trueAndFalse) {
|
for (boolean brittles : Iterate.trueAndFalse) {
|
||||||
for (BlockInfo block : blocks.values()) {
|
for (BlockInfo block : blocks.values()) {
|
||||||
if (brittles != BlockMovementTraits.isBrittle(block.state))
|
if (brittles != BlockMovementTraits.isBrittle(block.state))
|
||||||
|
@ -465,7 +535,11 @@ public abstract class Contraption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation,
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
|
addBlocksToWorld(world, offset, rotation, (pos, state) -> false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation,
|
||||||
BiPredicate<BlockPos, BlockState> customPlacement) {
|
BiPredicate<BlockPos, BlockState> customPlacement) {
|
||||||
stop(world);
|
stop(world);
|
||||||
|
|
||||||
|
@ -497,8 +571,16 @@ public abstract class Contraption {
|
||||||
&& !blockState.getCollisionShape(world, targetPos).isEmpty())
|
&& !blockState.getCollisionShape(world, targetPos).isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
world.destroyBlock(targetPos, blockState.getCollisionShape(world, targetPos).isEmpty());
|
world.destroyBlock(targetPos, true);
|
||||||
world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING);
|
world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING);
|
||||||
|
|
||||||
|
boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal();
|
||||||
|
verticalRotation = verticalRotation && transform.rotation != Rotation.NONE;
|
||||||
|
if (verticalRotation) {
|
||||||
|
if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock)
|
||||||
|
world.destroyBlock(targetPos, true);
|
||||||
|
}
|
||||||
|
|
||||||
TileEntity tileEntity = world.getTileEntity(targetPos);
|
TileEntity tileEntity = world.getTileEntity(targetPos);
|
||||||
CompoundNBT tag = block.nbt;
|
CompoundNBT tag = block.nbt;
|
||||||
if (tileEntity != null && tag != null) {
|
if (tileEntity != null && tag != null) {
|
||||||
|
@ -506,32 +588,34 @@ public abstract class Contraption {
|
||||||
tag.putInt("y", targetPos.getY());
|
tag.putInt("y", targetPos.getY());
|
||||||
tag.putInt("z", targetPos.getZ());
|
tag.putInt("z", targetPos.getZ());
|
||||||
|
|
||||||
if (tileEntity instanceof BeltTileEntity) {
|
if (verticalRotation && tileEntity instanceof PulleyTileEntity) {
|
||||||
tag.remove("Length");
|
tag.remove("Offset");
|
||||||
tag.remove("Index");
|
tag.remove("InitialOffset");
|
||||||
tag.putBoolean("DontClearAttachments", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tileEntity.read(tag);
|
tileEntity.read(tag);
|
||||||
|
|
||||||
if (tileEntity instanceof KineticTileEntity) {
|
|
||||||
KineticTileEntity kineticTileEntity = (KineticTileEntity) tileEntity;
|
|
||||||
kineticTileEntity.source = null;
|
|
||||||
kineticTileEntity.setSpeed(0);
|
|
||||||
kineticTileEntity.network = null;
|
|
||||||
kineticTileEntity.attachKinetics();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storage.containsKey(block.pos)) {
|
if (storage.containsKey(block.pos)) {
|
||||||
MountedStorage mountedStorage = storage.get(block.pos);
|
MountedStorage mountedStorage = storage.get(block.pos);
|
||||||
if (mountedStorage.isWorking())
|
if (mountedStorage.isWorking())
|
||||||
mountedStorage.fill(tileEntity);
|
mountedStorage.fill(tileEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Pair<BlockPos, Direction> pair : superglue) {
|
||||||
|
BlockPos targetPos = transform.apply(pair.getKey());
|
||||||
|
Direction targetFacing = transform.transformFacing(pair.getValue());
|
||||||
|
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing);
|
||||||
|
if (entity.onValidSurface()) {
|
||||||
|
if (!world.isRemote)
|
||||||
|
world.addEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initActors(World world) {
|
public void initActors(World world) {
|
||||||
|
|
|
@ -12,16 +12,24 @@ import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.simibubi.create.AllEntities;
|
import com.simibubi.create.AllEntities;
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption;
|
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.material.PushReaction;
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.item.BoatEntity;
|
import net.minecraft.entity.item.BoatEntity;
|
||||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
|
@ -30,11 +38,14 @@ import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.network.datasync.DataParameter;
|
import net.minecraft.network.datasync.DataParameter;
|
||||||
import net.minecraft.network.datasync.DataSerializers;
|
import net.minecraft.network.datasync.DataSerializers;
|
||||||
import net.minecraft.network.datasync.EntityDataManager;
|
import net.minecraft.network.datasync.EntityDataManager;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.ReuseableStream;
|
import net.minecraft.util.ReuseableStream;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
|
@ -42,7 +53,6 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
|
||||||
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.fml.common.registry.IEntityAdditionalSpawnData;
|
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
|
@ -53,12 +63,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
protected Contraption contraption;
|
protected Contraption contraption;
|
||||||
protected float initialAngle;
|
protected float initialAngle;
|
||||||
|
protected float forcedAngle;
|
||||||
protected BlockPos controllerPos;
|
protected BlockPos controllerPos;
|
||||||
protected Vec3d motionBeforeStall;
|
protected Vec3d motionBeforeStall;
|
||||||
protected boolean stationary;
|
protected boolean stationary;
|
||||||
|
|
||||||
final List<Entity> collidingEntities = new ArrayList<>();
|
final List<Entity> collidingEntities = new ArrayList<>();
|
||||||
|
|
||||||
|
private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL);
|
||||||
private static final DataParameter<Boolean> STALLED =
|
private static final DataParameter<Boolean> STALLED =
|
||||||
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN);
|
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN);
|
||||||
|
|
||||||
|
@ -78,20 +90,27 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
super(entityTypeIn, worldIn);
|
super(entityTypeIn, worldIn);
|
||||||
motionBeforeStall = Vec3d.ZERO;
|
motionBeforeStall = Vec3d.ZERO;
|
||||||
stationary = entityTypeIn == AllEntities.STATIONARY_CONTRAPTION.type;
|
stationary = entityTypeIn == AllEntities.STATIONARY_CONTRAPTION.type;
|
||||||
|
forcedAngle = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) {
|
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) {
|
||||||
ContraptionEntity entity = new ContraptionEntity(AllEntities.CONTRAPTION.type, world);
|
ContraptionEntity entity = new ContraptionEntity(AllEntities.CONTRAPTION.type, world);
|
||||||
entity.contraption = contraption;
|
entity.contraption = contraption;
|
||||||
entity.initialAngle = initialAngle;
|
entity.initialAngle = initialAngle;
|
||||||
entity.prevYaw = initialAngle;
|
entity.forceYaw(initialAngle);
|
||||||
entity.yaw = initialAngle;
|
|
||||||
entity.targetYaw = initialAngle;
|
|
||||||
if (contraption != null)
|
if (contraption != null)
|
||||||
contraption.gatherStoredItems();
|
contraption.gatherStoredItems();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle,
|
||||||
|
Direction facing) {
|
||||||
|
ContraptionEntity entity = createMounted(world, contraption, initialAngle);
|
||||||
|
entity.forcedAngle = facing.getHorizontalAngle();
|
||||||
|
entity.forceYaw(entity.forcedAngle);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
public static ContraptionEntity createStationary(World world, Contraption contraption) {
|
public static ContraptionEntity createStationary(World world, Contraption contraption) {
|
||||||
ContraptionEntity entity = new ContraptionEntity(AllEntities.STATIONARY_CONTRAPTION.type, world);
|
ContraptionEntity entity = new ContraptionEntity(AllEntities.STATIONARY_CONTRAPTION.type, world);
|
||||||
entity.contraption = contraption;
|
entity.contraption = contraption;
|
||||||
|
@ -156,6 +175,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tickAsPassenger(Entity e) {
|
public void tickAsPassenger(Entity e) {
|
||||||
|
boolean rotationLock = false;
|
||||||
|
boolean pauseWhileRotating = false;
|
||||||
|
|
||||||
|
if (contraption instanceof MountedContraption) {
|
||||||
|
rotationLock = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATION_LOCKED;
|
||||||
|
pauseWhileRotating = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATE_PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
Entity riding = e;
|
Entity riding = e;
|
||||||
while (riding.getRidingEntity() != null)
|
while (riding.getRidingEntity() != null)
|
||||||
riding = riding.getRidingEntity();
|
riding = riding.getRidingEntity();
|
||||||
|
@ -163,20 +190,28 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
if (riding instanceof BoatEntity)
|
if (riding instanceof BoatEntity)
|
||||||
movementVector = getPositionVec().subtract(prevPosX, prevPosY, prevPosZ);
|
movementVector = getPositionVec().subtract(prevPosX, prevPosY, prevPosZ);
|
||||||
Vec3d motion = movementVector.normalize();
|
Vec3d motion = movementVector.normalize();
|
||||||
|
boolean rotating = false;
|
||||||
|
|
||||||
if (motion.length() > 0) {
|
if (!rotationLock) {
|
||||||
targetYaw = yawFromVector(motion);
|
if (motion.length() > 0) {
|
||||||
if (targetYaw < 0)
|
targetYaw = yawFromVector(motion);
|
||||||
targetYaw += 360;
|
if (targetYaw < 0)
|
||||||
if (yaw < 0)
|
targetYaw += 360;
|
||||||
yaw += 360;
|
if (yaw < 0)
|
||||||
|
yaw += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevYaw = yaw;
|
||||||
|
yaw = angleLerp(0.4f, yaw, targetYaw);
|
||||||
|
if (Math.abs(AngleHelper.getShortestAngleDiff(yaw, targetYaw)) < 1f)
|
||||||
|
yaw = targetYaw;
|
||||||
|
else
|
||||||
|
rotating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevYaw = yaw;
|
|
||||||
yaw = angleLerp(0.4f, yaw, targetYaw);
|
|
||||||
|
|
||||||
boolean wasStalled = isStalled();
|
boolean wasStalled = isStalled();
|
||||||
tickActors(movementVector);
|
if (!rotating || !pauseWhileRotating)
|
||||||
|
tickActors(movementVector);
|
||||||
if (isStalled()) {
|
if (isStalled()) {
|
||||||
if (!wasStalled)
|
if (!wasStalled)
|
||||||
motionBeforeStall = riding.getMotion();
|
motionBeforeStall = riding.getMotion();
|
||||||
|
@ -188,6 +223,39 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
motionBeforeStall = Vec3d.ZERO;
|
motionBeforeStall = Vec3d.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isStalled() && (riding instanceof FurnaceMinecartEntity)) {
|
||||||
|
FurnaceMinecartEntity furnaceCart = (FurnaceMinecartEntity) riding;
|
||||||
|
CompoundNBT nbt = furnaceCart.serializeNBT();
|
||||||
|
int fuel = nbt.getInt("Fuel");
|
||||||
|
int fuelBefore = fuel;
|
||||||
|
double pushX = nbt.getDouble("PushX");
|
||||||
|
double pushZ = nbt.getDouble("PushZ");
|
||||||
|
|
||||||
|
int i = MathHelper.floor(furnaceCart.getX());
|
||||||
|
int j = MathHelper.floor(furnaceCart.getY());
|
||||||
|
int k = MathHelper.floor(furnaceCart.getZ());
|
||||||
|
if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k)).isIn(BlockTags.RAILS))
|
||||||
|
--j;
|
||||||
|
|
||||||
|
BlockPos blockpos = new BlockPos(i, j, k);
|
||||||
|
BlockState blockstate = this.world.getBlockState(blockpos);
|
||||||
|
if (furnaceCart.canUseRail() && blockstate.isIn(BlockTags.RAILS))
|
||||||
|
if (fuel > 1)
|
||||||
|
riding.setMotion(riding.getMotion().normalize().scale(1));
|
||||||
|
if (fuel < 5 && contraption != null) {
|
||||||
|
ItemStack coal = ItemHelper.extract(contraption.inventory, FUEL_ITEMS, 1, false);
|
||||||
|
if (!coal.isEmpty())
|
||||||
|
fuel += 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fuel != fuelBefore || pushX != 0 || pushZ != 0) {
|
||||||
|
nbt.putInt("Fuel", fuel);
|
||||||
|
nbt.putDouble("PushX", 0);
|
||||||
|
nbt.putDouble("PushZ", 0);
|
||||||
|
furnaceCart.deserializeNBT(nbt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.tick();
|
super.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,12 +278,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
Vec3d actorPosition = new Vec3d(blockInfo.pos);
|
Vec3d actorPosition = new Vec3d(blockInfo.pos);
|
||||||
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
|
actorPosition = actorPosition.add(actor.getActiveAreaOffset(context));
|
||||||
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
|
actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch);
|
||||||
actorPosition = actorPosition.add(rotationOffset).add(getPositionVec());
|
actorPosition = actorPosition.add(rotationOffset).add(getAnchorVec());
|
||||||
|
|
||||||
boolean newPosVisited = false;
|
boolean newPosVisited = false;
|
||||||
BlockPos gridPosition = new BlockPos(actorPosition);
|
BlockPos gridPosition = new BlockPos(actorPosition);
|
||||||
|
|
||||||
if (!stalledPreviously) {
|
if (!context.stall) {
|
||||||
Vec3d previousPosition = context.position;
|
Vec3d previousPosition = context.position;
|
||||||
if (previousPosition != null) {
|
if (previousPosition != null) {
|
||||||
context.motion = actorPosition.subtract(previousPosition);
|
context.motion = actorPosition.subtract(previousPosition);
|
||||||
|
@ -245,13 +313,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.rotation = rotationVec;
|
context.rotation = rotationVec;
|
||||||
context.position = actorPosition;
|
context.position = actorPosition;
|
||||||
|
|
||||||
if (actor.isActive(context)) {
|
if (actor.isActive(context)) {
|
||||||
if (newPosVisited && !context.stall) {
|
if (newPosVisited && !context.stall) {
|
||||||
actor.visitNewPosition(context, gridPosition);
|
actor.visitNewPosition(context, gridPosition);
|
||||||
|
@ -280,6 +346,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
setPosition(x + getX() + x, getY() + y, getZ() + z);
|
setPosition(x + getX() + x, getY() + y, getZ() + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vec3d getAnchorVec() {
|
||||||
|
if (contraption != null && contraption.getType() == AllContraptionTypes.MOUNTED)
|
||||||
|
return new Vec3d(getX() - .5, getY(), getZ() - .5);
|
||||||
|
return getPositionVec();
|
||||||
|
}
|
||||||
|
|
||||||
public void rotateTo(double roll, double yaw, double pitch) {
|
public void rotateTo(double roll, double yaw, double pitch) {
|
||||||
rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw),
|
rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw),
|
||||||
getShortestAngleDiff(this.pitch, pitch));
|
getShortestAngleDiff(this.pitch, pitch));
|
||||||
|
@ -298,23 +370,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPosition(double x, double y, double z) {
|
public void setPosition(double x, double y, double z) {
|
||||||
Entity e = getRidingEntity();
|
super.setPosition(x, y, z);
|
||||||
if (e != null && e instanceof AbstractMinecartEntity) {
|
|
||||||
Entity riding = e;
|
|
||||||
while (riding.getRidingEntity() != null)
|
|
||||||
riding = riding.getRidingEntity();
|
|
||||||
x = riding.getX() - .5;
|
|
||||||
z = riding.getZ() - .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setPos(x, y, z);
|
|
||||||
|
|
||||||
if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld)
|
|
||||||
((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving.
|
|
||||||
if (contraption != null) {
|
if (contraption != null) {
|
||||||
AxisAlignedBB cbox = contraption.getBoundingBox();
|
AxisAlignedBB cbox = contraption.getBoundingBox();
|
||||||
if (cbox != null)
|
if (cbox != null) {
|
||||||
this.setBoundingBox(cbox.offset(x, y, z));
|
Vec3d actualVec = getAnchorVec();
|
||||||
|
this.setBoundingBox(cbox.offset(actualVec));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +424,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
protected void readAdditional(CompoundNBT compound) {
|
protected void readAdditional(CompoundNBT compound) {
|
||||||
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
|
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
|
||||||
initialAngle = compound.getFloat("InitialAngle");
|
initialAngle = compound.getFloat("InitialAngle");
|
||||||
targetYaw = yaw = prevYaw = initialAngle;
|
forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle);
|
||||||
dataManager.set(STALLED, compound.getBoolean("Stalled"));
|
dataManager.set(STALLED, compound.getBoolean("Stalled"));
|
||||||
ListNBT vecNBT = compound.getList("CachedMotion", 6);
|
ListNBT vecNBT = compound.getList("CachedMotion", 6);
|
||||||
if (!vecNBT.isEmpty()) {
|
if (!vecNBT.isEmpty()) {
|
||||||
|
@ -375,6 +437,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forceYaw(float forcedYaw) {
|
||||||
|
targetYaw = yaw = prevYaw = forcedYaw;
|
||||||
|
}
|
||||||
|
|
||||||
public void checkController() {
|
public void checkController() {
|
||||||
if (controllerPos == null)
|
if (controllerPos == null)
|
||||||
return;
|
return;
|
||||||
|
@ -394,14 +460,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeAdditional(CompoundNBT compound) {
|
protected void writeAdditional(CompoundNBT compound) {
|
||||||
compound.put("Contraption", getContraption().writeNBT());
|
if (contraption != null)
|
||||||
compound.putFloat("InitialAngle", initialAngle);
|
compound.put("Contraption", contraption.writeNBT());
|
||||||
if (!stationary)
|
if (!stationary && motionBeforeStall != null)
|
||||||
compound.put("CachedMotion",
|
compound.put("CachedMotion",
|
||||||
newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
|
newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z));
|
||||||
compound.putBoolean("Stalled", isStalled());
|
|
||||||
if (controllerPos != null)
|
if (controllerPos != null)
|
||||||
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
|
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
|
||||||
|
if (forcedAngle != -1)
|
||||||
|
compound.putFloat("ForcedYaw", forcedAngle);
|
||||||
|
|
||||||
|
compound.putFloat("InitialAngle", initialAngle);
|
||||||
|
compound.putBoolean("Stalled", isStalled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -423,9 +493,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
|
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (getContraption() != null) {
|
if (getContraption() != null) {
|
||||||
BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5));
|
BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5));
|
||||||
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
||||||
getContraption().disassemble(world, offset, rotation);
|
getContraption().addBlocksToWorld(world, offset, rotation);
|
||||||
preventMovedEntitiesFromGettingStuck();
|
preventMovedEntitiesFromGettingStuck();
|
||||||
}
|
}
|
||||||
remove();
|
remove();
|
||||||
|
@ -532,4 +602,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
super.setMotion(vec);
|
super.setMotion(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeCollidedWith() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getInitialAngle() {
|
||||||
|
return initialAngle;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
@ -37,6 +38,8 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
||||||
return;
|
return;
|
||||||
if (entity.getContraption() == null)
|
if (entity.getContraption() == null)
|
||||||
return;
|
return;
|
||||||
|
if (entity.getContraption().getType() == AllContraptionTypes.MOUNTED && entity.getRidingEntity() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO 1.15 buffered render
|
// TODO 1.15 buffered render
|
||||||
RenderSystem.pushMatrix();
|
RenderSystem.pushMatrix();
|
||||||
|
@ -78,6 +81,7 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
||||||
|
|
||||||
RenderSystem.translatef((float) cartX, (float) cartY, (float) cartZ);
|
RenderSystem.translatef((float) cartX, (float) cartY, (float) cartZ);
|
||||||
}
|
}
|
||||||
|
GlStateManager.translatef(-.5f, 0, -.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
|
|
|
@ -1,23 +1,17 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL13;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.config.AllConfigs;
|
|
||||||
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
|
import com.simibubi.create.foundation.utility.PlacementSimulationWorld;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
|
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.render.StructureRenderer;
|
||||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockRenderType;
|
import net.minecraft.block.BlockRenderType;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -26,15 +20,9 @@ import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import net.minecraft.client.renderer.RenderHelper;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.crash.ReportedException;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
|
@ -46,59 +34,19 @@ public class ContraptionRenderer {
|
||||||
|
|
||||||
public static final Compartment<Contraption> CONTRAPTION = new Compartment<>();
|
public static final Compartment<Contraption> CONTRAPTION = new Compartment<>();
|
||||||
protected static PlacementSimulationWorld renderWorld;
|
protected static PlacementSimulationWorld renderWorld;
|
||||||
protected static LightingWorld lightingWorld;
|
|
||||||
|
|
||||||
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, MatrixStack ms, BufferBuilder buffer) {
|
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, MatrixStack ms,
|
||||||
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c, ms));
|
BufferBuilder buffer) {
|
||||||
|
SuperByteBuffer contraptionBuffer =
|
||||||
|
CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c, ms));
|
||||||
transform.accept(contraptionBuffer);
|
transform.accept(contraptionBuffer);
|
||||||
contraptionBuffer.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(ms, buffer);
|
contraptionBuffer.light((lx, ly, lz) -> getLight(world, lx, ly, lz)).renderInto(ms, buffer);
|
||||||
renderActors(world, c, transform, ms, buffer);
|
renderActors(world, c, transform, ms, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderTEsWithGL(World world, Contraption c, Vec3d position, Vec3d rotation, MatrixStack ms, IRenderTypeBuffer buffer) {
|
public static void renderTEsWithGL(World world, Contraption c, Vec3d position, Vec3d rotation, MatrixStack ms,
|
||||||
float pt = Minecraft.getInstance().getRenderPartialTicks();
|
IRenderTypeBuffer buffer) {
|
||||||
|
StructureRenderer.renderTileEntities(world, position, rotation, c.customRenderTEs, ms, buffer);
|
||||||
if (lightingWorld == null)
|
|
||||||
lightingWorld = new LightingWorld(world);
|
|
||||||
lightingWorld.setWorld(world);
|
|
||||||
lightingWorld.setTransform(position, rotation);
|
|
||||||
|
|
||||||
for (Iterator<TileEntity> iterator = c.customRenderTEs.iterator(); iterator.hasNext();) {
|
|
||||||
TileEntity tileEntity = iterator.next();
|
|
||||||
if (TileEntityRendererDispatcher.instance.getRenderer(tileEntity) == null) {
|
|
||||||
iterator.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
BlockPos pos = tileEntity.getPos();
|
|
||||||
if (!tileEntity.hasFastRenderer()) {
|
|
||||||
RenderHelper.enable();
|
|
||||||
int i = WorldRenderer.getLightmapCoordinates(lightingWorld, pos);
|
|
||||||
int j = LightTexture.getBlockLightCoordinates(i);
|
|
||||||
int k = LightTexture.getSkyLightCoordinates(i);
|
|
||||||
RenderSystem.glMultiTexCoord2f(GL13.GL_TEXTURE1, (float) j, (float) k);
|
|
||||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
World prevTileWorld = tileEntity.getWorld();
|
|
||||||
tileEntity.setLocation(lightingWorld, pos);
|
|
||||||
TileEntityRendererDispatcher.instance.render(tileEntity, pt, ms, buffer);
|
|
||||||
tileEntity.setLocation(prevTileWorld, pos);
|
|
||||||
|
|
||||||
} catch (ReportedException e) {
|
|
||||||
if (AllConfigs.CLIENT.explainRenderErrors.get()) {
|
|
||||||
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
|
|
||||||
+ " didn't want to render while moved.\n", e);
|
|
||||||
} else {
|
|
||||||
Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString()
|
|
||||||
+ " didn't want to render while moved.\n");
|
|
||||||
}
|
|
||||||
iterator.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SuperByteBuffer renderContraption(Contraption c, MatrixStack ms) {
|
private static SuperByteBuffer renderContraption(Contraption c, MatrixStack ms) {
|
||||||
|
@ -130,8 +78,8 @@ public class ContraptionRenderer {
|
||||||
return new SuperByteBuffer(builder);
|
return new SuperByteBuffer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderActors(World world, Contraption c, Consumer<SuperByteBuffer> transform,
|
private static void renderActors(World world, Contraption c, Consumer<SuperByteBuffer> transform, MatrixStack ms,
|
||||||
MatrixStack ms, BufferBuilder buffer) {
|
BufferBuilder buffer) {
|
||||||
for (Pair<BlockInfo, MovementContext> actor : c.getActors()) {
|
for (Pair<BlockInfo, MovementContext> actor : c.getActors()) {
|
||||||
MovementContext context = actor.getRight();
|
MovementContext context = actor.getRight();
|
||||||
if (context == null)
|
if (context == null)
|
||||||
|
@ -171,36 +119,4 @@ public class ContraptionRenderer {
|
||||||
return ((int) sky) << 20 | ((int) block) << 4;
|
return ((int) sky) << 20 | ((int) block) << 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LightingWorld extends WrappedWorld {
|
|
||||||
|
|
||||||
private Vec3d offset;
|
|
||||||
private Vec3d rotation;
|
|
||||||
|
|
||||||
public LightingWorld(World world) {
|
|
||||||
super(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWorld(World world) {
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTransform(Vec3d offset, Vec3d rotation) {
|
|
||||||
this.offset = offset;
|
|
||||||
this.rotation = rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBaseLightLevel(BlockPos pos, int minLight) {
|
|
||||||
return super.getBaseLightLevel(transformPos(pos), minLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockPos transformPos(BlockPos pos) {
|
|
||||||
Vec3d vec = VecHelper.getCenterOf(pos);
|
|
||||||
vec = VecHelper.rotate(vec, rotation.x, rotation.y, rotation.z);
|
|
||||||
vec = vec.add(offset).subtract(VecHelper.getCenterOf(BlockPos.ZERO));
|
|
||||||
return new BlockPos(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,14 +163,14 @@ public class StructureTransform {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Axis transformAxis(Axis axisIn) {
|
public Axis transformAxis(Axis axisIn) {
|
||||||
Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn);
|
Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn);
|
||||||
facing = transformFacing(facing);
|
facing = transformFacing(facing);
|
||||||
Axis axis = facing.getAxis();
|
Axis axis = facing.getAxis();
|
||||||
return axis;
|
return axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Direction transformFacing(Direction facing) {
|
public Direction transformFacing(Direction facing) {
|
||||||
for (int i = 0; i < rotation.ordinal(); i++)
|
for (int i = 0; i < rotation.ordinal(); i++)
|
||||||
facing = DirectionHelper.rotateAround(facing, rotationAxis);
|
facing = DirectionHelper.rotateAround(facing, rotationAxis);
|
||||||
return facing;
|
return facing;
|
||||||
|
|
|
@ -36,6 +36,11 @@ public class BearingContraption extends Contraption {
|
||||||
return construct;
|
return construct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||||
|
return pos.equals(anchor.offset(facing.getOpposite()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> capture) {
|
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> capture) {
|
||||||
BlockPos localPos = pos.subtract(anchor);
|
BlockPos localPos = pos.subtract(anchor);
|
||||||
|
|
|
@ -7,7 +7,6 @@ import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
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 net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
|
@ -148,6 +148,9 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assemble() {
|
public void assemble() {
|
||||||
|
if (!(world.getBlockState(pos).getBlock() instanceof ClockworkBearingBlock))
|
||||||
|
return;
|
||||||
|
|
||||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||||
|
|
||||||
// Collect Construct
|
// Collect Construct
|
||||||
|
@ -182,7 +185,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (!running)
|
if (!running && hourHand == null && minuteHand == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hourAngle = 0;
|
hourAngle = 0;
|
||||||
|
@ -217,8 +220,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
||||||
this.minuteHand = contraption;
|
this.minuteHand = contraption;
|
||||||
minuteHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
minuteHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
||||||
}
|
}
|
||||||
if (!world.isRemote)
|
if (!world.isRemote) {
|
||||||
|
this.running = true;
|
||||||
sendData();
|
sendData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,6 +32,11 @@ public class ClockworkContraption extends Contraption {
|
||||||
ignoreBlocks.add(anchor.add(blockPos));
|
ignoreBlocks.add(anchor.add(blockPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||||
|
return pos.equals(anchor.offset(facing.getOpposite(), offset + 1));
|
||||||
|
}
|
||||||
|
|
||||||
public static Pair<ClockworkContraption, ClockworkContraption> assembleClockworkAt(World world, BlockPos pos,
|
public static Pair<ClockworkContraption, ClockworkContraption> assembleClockworkAt(World world, BlockPos pos,
|
||||||
Direction direction) {
|
Direction direction) {
|
||||||
if (isFrozen())
|
if (isFrozen())
|
||||||
|
|
|
@ -150,6 +150,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assemble() {
|
public void assemble() {
|
||||||
|
if (!(world.getBlockState(pos).getBlock() instanceof MechanicalBearingBlock))
|
||||||
|
return;
|
||||||
|
|
||||||
Direction direction = getBlockState().get(FACING);
|
Direction direction = getBlockState().get(FACING);
|
||||||
|
|
||||||
// Collect Construct
|
// Collect Construct
|
||||||
|
@ -161,6 +164,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
if (contraption.blocks.isEmpty())
|
if (contraption.blocks.isEmpty())
|
||||||
return;
|
return;
|
||||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||||
|
|
||||||
movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this);
|
movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this);
|
||||||
BlockPos anchor = pos.offset(direction);
|
BlockPos anchor = pos.offset(direction);
|
||||||
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
||||||
|
@ -180,7 +184,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (!running)
|
if (!running && movedContraption == null)
|
||||||
return;
|
return;
|
||||||
if (movedContraption != null)
|
if (movedContraption != null)
|
||||||
movedContraption.disassemble();
|
movedContraption.disassemble();
|
||||||
|
@ -267,8 +271,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
||||||
markDirty();
|
markDirty();
|
||||||
BlockPos anchor = pos.offset(blockState.get(FACING));
|
BlockPos anchor = pos.offset(blockState.get(FACING));
|
||||||
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ());
|
||||||
if (!world.isRemote)
|
if (!world.isRemote) {
|
||||||
|
this.running = true;
|
||||||
sendData();
|
sendData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -167,11 +167,7 @@ public class ChassisTileEntity extends SmartTileEntity {
|
||||||
// Ignore replaceable Blocks and Air-like
|
// Ignore replaceable Blocks and Air-like
|
||||||
if (!BlockMovementTraits.movementNecessary(world, current))
|
if (!BlockMovementTraits.movementNecessary(world, current))
|
||||||
break;
|
break;
|
||||||
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(currentState))
|
if (BlockMovementTraits.isBrittle(currentState))
|
||||||
break;
|
|
||||||
if (AllBlocks.MECHANICAL_PISTON.typeOf(currentState))
|
|
||||||
break;
|
|
||||||
if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(currentState))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
positions.add(current);
|
positions.add(current);
|
||||||
|
@ -212,6 +208,8 @@ public class ChassisTileEntity extends SmartTileEntity {
|
||||||
continue;
|
continue;
|
||||||
if (!BlockMovementTraits.movementNecessary(world, searchPos))
|
if (!BlockMovementTraits.movementNecessary(world, searchPos))
|
||||||
continue;
|
continue;
|
||||||
|
if (BlockMovementTraits.isBrittle(searchedState))
|
||||||
|
continue;
|
||||||
|
|
||||||
localVisited.add(searchPos);
|
localVisited.add(searchPos);
|
||||||
if (!searchPos.equals(pos))
|
if (!searchPos.equals(pos))
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class GlueEffectPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
private BlockPos pos;
|
||||||
|
private Direction direction;
|
||||||
|
private boolean fullBlock;
|
||||||
|
|
||||||
|
public GlueEffectPacket(BlockPos pos, Direction direction, boolean fullBlock) {
|
||||||
|
this.pos = pos;
|
||||||
|
this.direction = direction;
|
||||||
|
this.fullBlock = fullBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlueEffectPacket(PacketBuffer buffer) {
|
||||||
|
pos = buffer.readBlockPos();
|
||||||
|
direction = Direction.byIndex(buffer.readByte());
|
||||||
|
fullBlock = buffer.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeBlockPos(pos);
|
||||||
|
buffer.writeByte(direction.getIndex());
|
||||||
|
buffer.writeBoolean(fullBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
if (!mc.player.getPosition().withinDistance(pos, 100))
|
||||||
|
return;
|
||||||
|
SuperGlueItem.spawnParticles(mc.world, pos, direction, fullBlock);
|
||||||
|
}));
|
||||||
|
context.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,369 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllEntities;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.AllSoundEvents;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntitySize;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.MoverType;
|
||||||
|
import net.minecraft.entity.Pose;
|
||||||
|
import net.minecraft.entity.effect.LightningBoltEntity;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.network.IPacket;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
|
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||||
|
|
||||||
|
private int validationTimer;
|
||||||
|
protected BlockPos hangingPosition;
|
||||||
|
protected Direction facingDirection = Direction.SOUTH;
|
||||||
|
|
||||||
|
public SuperGlueEntity(EntityType<?> type, World world) {
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuperGlueEntity(World world, BlockPos pos, Direction direction) {
|
||||||
|
this(AllEntities.SUPER_GLUE.type, world);
|
||||||
|
hangingPosition = pos;
|
||||||
|
facingDirection = direction;
|
||||||
|
updateFacingWithBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidthPixels() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeightPixels() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBroken(@Nullable Entity breaker) {
|
||||||
|
playSound(SoundEvents.ENTITY_SLIME_SQUISH_SMALL, 1.0F, 1.0F);
|
||||||
|
if (onValidSurface()) {
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new GlueEffectPacket(getHangingPosition(), getFacingDirection().getOpposite(), false));
|
||||||
|
playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.5F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playPlaceSound() {
|
||||||
|
playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.75F);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateFacingWithBoundingBox() {
|
||||||
|
Validate.notNull(getFacingDirection());
|
||||||
|
if (getFacingDirection().getAxis().isHorizontal()) {
|
||||||
|
this.rotationPitch = 0.0F;
|
||||||
|
this.rotationYaw = getFacingDirection().getHorizontalIndex() * 90;
|
||||||
|
} else {
|
||||||
|
this.rotationPitch = -90 * getFacingDirection().getAxisDirection().getOffset();
|
||||||
|
this.rotationYaw = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.prevRotationPitch = this.rotationPitch;
|
||||||
|
this.prevRotationYaw = this.rotationYaw;
|
||||||
|
this.updateBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateBoundingBox() {
|
||||||
|
if (this.getFacingDirection() != null) {
|
||||||
|
double x = hangingPosition.getX() + 0.5 - facingDirection.getXOffset() * 0.5;
|
||||||
|
double y = hangingPosition.getY() + 0.5 - facingDirection.getYOffset() * 0.5;
|
||||||
|
double z = hangingPosition.getZ() + 0.5 - facingDirection.getZOffset() * 0.5;
|
||||||
|
this.setPos(x, y, z);
|
||||||
|
double d1 = (double) this.getWidthPixels();
|
||||||
|
double d2 = (double) this.getHeightPixels();
|
||||||
|
double d3 = (double) this.getWidthPixels();
|
||||||
|
Axis axis = this.getFacingDirection().getAxis();
|
||||||
|
double depth = 2 - 1 / 128f;
|
||||||
|
|
||||||
|
switch (axis) {
|
||||||
|
case X:
|
||||||
|
d1 = depth;
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
d2 = depth;
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
d3 = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
d1 = d1 / 32.0D;
|
||||||
|
d2 = d2 / 32.0D;
|
||||||
|
d3 = d3 / 32.0D;
|
||||||
|
this.setBoundingBox(new AxisAlignedBB(x - d1, y - d2, z - d3, x + d1, y + d2, z + d3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (this.validationTimer++ == 10 && !this.world.isRemote) {
|
||||||
|
this.validationTimer = 0;
|
||||||
|
if (isAlive() && !this.onValidSurface()) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onValidSurface() {
|
||||||
|
BlockPos pos = hangingPosition;
|
||||||
|
BlockPos pos2 = hangingPosition.offset(getFacingDirection().getOpposite());
|
||||||
|
if (!world.isAreaLoaded(pos, 0) || !world.isAreaLoaded(pos2, 0))
|
||||||
|
return true;
|
||||||
|
if (world.isAirBlock(pos) && world.isAirBlock(pos2))
|
||||||
|
return false;
|
||||||
|
return world.getEntitiesInAABBexcluding(this, getBoundingBox(), e -> e instanceof SuperGlueEntity).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeCollidedWith() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hitByEntity(Entity entity) {
|
||||||
|
return entity instanceof PlayerEntity
|
||||||
|
? attackEntityFrom(DamageSource.causePlayerDamage((PlayerEntity) entity), 0)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Direction getHorizontalFacing() {
|
||||||
|
return this.getFacingDirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||||
|
if (this.isInvulnerableTo(source))
|
||||||
|
return false;
|
||||||
|
if (isAlive() && !world.isRemote) {
|
||||||
|
remove();
|
||||||
|
markVelocityChanged();
|
||||||
|
onBroken(source.getTrueSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(MoverType typeIn, Vec3d pos) {
|
||||||
|
if (!world.isRemote && isAlive() && pos.lengthSquared() > 0.0D) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addVelocity(double x, double y, double z) {
|
||||||
|
if (!world.isRemote && isAlive() && x * x + y * y + z * z > 0.0D) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getEyeHeight(Pose poseIn, EntitySize sizeIn) {
|
||||||
|
return 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getPickedResult(RayTraceResult target) {
|
||||||
|
return AllItems.SUPER_GLUE.asStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyEntityCollision(Entity entityIn) {
|
||||||
|
super.applyEntityCollision(entityIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processInitialInteract(PlayerEntity player, Hand hand) {
|
||||||
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
triggerPlaceBlock(player, hand);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void triggerPlaceBlock(PlayerEntity player, Hand hand) {
|
||||||
|
if (player instanceof ClientPlayerEntity && player.world instanceof ClientWorld) {
|
||||||
|
ClientPlayerEntity cPlayer = (ClientPlayerEntity) player;
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
RayTraceResult ray =
|
||||||
|
cPlayer.pick(mc.playerController.getBlockReachDistance(), mc.getRenderPartialTicks(), false);
|
||||||
|
if (ray instanceof BlockRayTraceResult) {
|
||||||
|
for (Hand handIn : Hand.values()) {
|
||||||
|
ItemStack itemstack = cPlayer.getHeldItem(handIn);
|
||||||
|
int countBefore = itemstack.getCount();
|
||||||
|
ActionResultType actionResultType = mc.playerController.func_217292_a(cPlayer,
|
||||||
|
(ClientWorld) cPlayer.world, handIn, (BlockRayTraceResult) ray);
|
||||||
|
if (actionResultType == ActionResultType.SUCCESS) {
|
||||||
|
cPlayer.swingArm(handIn);
|
||||||
|
if (!itemstack.isEmpty()
|
||||||
|
&& (itemstack.getCount() != countBefore || mc.playerController.isInCreativeMode()))
|
||||||
|
mc.gameRenderer.itemRenderer.resetEquippedProgress(handIn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeAdditional(CompoundNBT compound) {
|
||||||
|
compound.putByte("Facing", (byte) this.getFacingDirection().getIndex());
|
||||||
|
BlockPos blockpos = this.getHangingPosition();
|
||||||
|
compound.putInt("TileX", blockpos.getX());
|
||||||
|
compound.putInt("TileY", blockpos.getY());
|
||||||
|
compound.putInt("TileZ", blockpos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readAdditional(CompoundNBT compound) {
|
||||||
|
this.hangingPosition =
|
||||||
|
new BlockPos(compound.getInt("TileX"), compound.getInt("TileY"), compound.getInt("TileZ"));
|
||||||
|
this.facingDirection = Direction.byIndex(compound.getByte("Facing"));
|
||||||
|
updateFacingWithBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemEntity entityDropItem(ItemStack stack, float yOffset) {
|
||||||
|
float xOffset = (float) this.getFacingDirection().getXOffset() * 0.15F;
|
||||||
|
float zOffset = (float) this.getFacingDirection().getZOffset() * 0.15F;
|
||||||
|
ItemEntity itementity =
|
||||||
|
new ItemEntity(this.world, this.getX() + xOffset, this.getY() + yOffset, this.getZ() + zOffset, stack);
|
||||||
|
itementity.setDefaultPickupDelay();
|
||||||
|
this.world.addEntity(itementity);
|
||||||
|
return itementity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldSetPosAfterLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPosition(double x, double y, double z) {
|
||||||
|
hangingPosition = new BlockPos(x, y, z);
|
||||||
|
updateBoundingBox();
|
||||||
|
isAirBorne = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getRotatedYaw(Rotation transformRotation) {
|
||||||
|
if (this.getFacingDirection().getAxis() != Direction.Axis.Y) {
|
||||||
|
switch (transformRotation) {
|
||||||
|
case CLOCKWISE_180:
|
||||||
|
this.facingDirection = this.getFacingDirection().getOpposite();
|
||||||
|
break;
|
||||||
|
case COUNTERCLOCKWISE_90:
|
||||||
|
this.facingDirection = this.getFacingDirection().rotateYCCW();
|
||||||
|
break;
|
||||||
|
case CLOCKWISE_90:
|
||||||
|
this.facingDirection = this.getFacingDirection().rotateY();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float f = MathHelper.wrapDegrees(this.rotationYaw);
|
||||||
|
switch (transformRotation) {
|
||||||
|
case CLOCKWISE_180:
|
||||||
|
return f + 180.0F;
|
||||||
|
case COUNTERCLOCKWISE_90:
|
||||||
|
return f + 90.0F;
|
||||||
|
case CLOCKWISE_90:
|
||||||
|
return f + 270.0F;
|
||||||
|
default:
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getHangingPosition() {
|
||||||
|
return this.hangingPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMirroredYaw(Mirror transformMirror) {
|
||||||
|
return this.getRotatedYaw(transformMirror.toRotation(this.getFacingDirection()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getAttachedDirection(BlockPos pos) {
|
||||||
|
return !pos.equals(hangingPosition) ? getFacingDirection() : getFacingDirection().getOpposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStruckByLightning(LightningBoltEntity lightningBolt) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recalculateSize() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
EntityType.Builder<SuperGlueEntity> entityBuilder = (EntityType.Builder<SuperGlueEntity>) builder;
|
||||||
|
return entityBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPacket<?> createSpawnPacket() {
|
||||||
|
return NetworkHooks.getEntitySpawningPacket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSpawnData(PacketBuffer buffer) {
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
writeAdditional(compound);
|
||||||
|
buffer.writeCompoundTag(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSpawnData(PacketBuffer additionalData) {
|
||||||
|
readAdditional(additionalData.readCompoundTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getFacingDirection() {
|
||||||
|
return facingDirection;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.foundation.utility.RayTraceWorld;
|
||||||
|
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.RayTraceResult.Type;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
|
@EventBusSubscriber
|
||||||
|
public class SuperGlueHandler {
|
||||||
|
|
||||||
|
public static Map<Direction, SuperGlueEntity> gatherGlue(IWorld world, BlockPos pos) {
|
||||||
|
List<SuperGlueEntity> entities = world.getEntitiesWithinAABB(SuperGlueEntity.class, new AxisAlignedBB(pos));
|
||||||
|
Map<Direction, SuperGlueEntity> map = new HashMap<>();
|
||||||
|
for (SuperGlueEntity entity : entities)
|
||||||
|
map.put(entity.getAttachedDirection(pos), entity);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void glueListensForBlockPlacement(EntityPlaceEvent event) {
|
||||||
|
IWorld world = event.getWorld();
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
BlockPos pos = event.getPos();
|
||||||
|
|
||||||
|
if (entity == null || world == null || pos == null)
|
||||||
|
return;
|
||||||
|
if (event.isCanceled())
|
||||||
|
return;
|
||||||
|
if (world.isRemote())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Map<Direction, SuperGlueEntity> gatheredGlue = gatherGlue(world, pos);
|
||||||
|
for (Direction direction : gatheredGlue.keySet())
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity),
|
||||||
|
new GlueEffectPacket(pos, direction, true));
|
||||||
|
|
||||||
|
if (entity instanceof PlayerEntity)
|
||||||
|
glueInOffHandAppliesOnBlockPlace(event, pos, (PlayerEntity) entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void glueInOffHandAppliesOnBlockPlace(EntityPlaceEvent event, BlockPos pos, PlayerEntity placer) {
|
||||||
|
ItemStack itemstack = placer.getHeldItemOffhand();
|
||||||
|
if (!AllItems.SUPER_GLUE.typeOf(itemstack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE).getValue();
|
||||||
|
Vec3d start = placer.getEyePosition(1);
|
||||||
|
Vec3d look = placer.getLook(1);
|
||||||
|
Vec3d end = start.add(look.x * distance, look.y * distance, look.z * distance);
|
||||||
|
World world = placer.world;
|
||||||
|
|
||||||
|
RayTraceWorld rayTraceWorld =
|
||||||
|
new RayTraceWorld(world, (p, state) -> p.equals(pos) ? Blocks.AIR.getDefaultState() : state);
|
||||||
|
BlockRayTraceResult ray = rayTraceWorld.rayTraceBlocks(new RayTraceContext(start, end,
|
||||||
|
RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, placer));
|
||||||
|
|
||||||
|
Direction face = ray.getFace();
|
||||||
|
if (ray == null || face == null || ray.getType() == Type.MISS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ray.getPos().offset(face).equals(pos)) {
|
||||||
|
event.setCanceled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, ray.getPos(), face.getOpposite());
|
||||||
|
CompoundNBT compoundnbt = itemstack.getTag();
|
||||||
|
if (compoundnbt != null)
|
||||||
|
EntityType.applyItemNBT(world, placer, entity, compoundnbt);
|
||||||
|
|
||||||
|
if (entity.onValidSurface()) {
|
||||||
|
if (!world.isRemote) {
|
||||||
|
entity.playPlaceSound();
|
||||||
|
world.addEntity(entity);
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity),
|
||||||
|
new GlueEffectPacket(ray.getPos(), face, true));
|
||||||
|
}
|
||||||
|
itemstack.damageItem(1, placer, SuperGlueItem::onBroken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.particles.ItemParticleData;
|
||||||
|
import net.minecraft.particles.ParticleTypes;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public class SuperGlueItem extends Item {
|
||||||
|
|
||||||
|
public SuperGlueItem(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDamageable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxDamage(ItemStack stack) {
|
||||||
|
return 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemStackLimit(ItemStack stack) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResultType onItemUse(ItemUseContext context) {
|
||||||
|
BlockPos blockpos = context.getPos();
|
||||||
|
Direction direction = context.getFace();
|
||||||
|
BlockPos blockpos1 = blockpos.offset(direction);
|
||||||
|
PlayerEntity playerentity = context.getPlayer();
|
||||||
|
ItemStack itemstack = context.getItem();
|
||||||
|
|
||||||
|
if (playerentity != null && !this.canPlace(playerentity, direction, itemstack, blockpos1))
|
||||||
|
return ActionResultType.FAIL;
|
||||||
|
|
||||||
|
World world = context.getWorld();
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, blockpos1, direction);
|
||||||
|
CompoundNBT compoundnbt = itemstack.getTag();
|
||||||
|
if (compoundnbt != null)
|
||||||
|
EntityType.applyItemNBT(world, playerentity, entity, compoundnbt);
|
||||||
|
|
||||||
|
if (!entity.onValidSurface())
|
||||||
|
return ActionResultType.FAIL;
|
||||||
|
|
||||||
|
if (!world.isRemote) {
|
||||||
|
entity.playPlaceSound();
|
||||||
|
world.addEntity(entity);
|
||||||
|
}
|
||||||
|
itemstack.damageItem(1, playerentity, SuperGlueItem::onBroken);
|
||||||
|
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onBroken(PlayerEntity player) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canPlace(PlayerEntity entity, Direction facing, ItemStack stack, BlockPos pos) {
|
||||||
|
return !World.isOutsideBuildHeight(pos) && entity.canPlayerEdit(pos, facing, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static void spawnParticles(World world, BlockPos pos, Direction direction, boolean fullBlock) {
|
||||||
|
Vec3d vec = new Vec3d(direction.getDirectionVec());
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(vec);
|
||||||
|
Vec3d facePos = VecHelper.getCenterOf(pos).add(vec.scale(.5f));
|
||||||
|
|
||||||
|
float distance = fullBlock ? 1f : .25f + .25f * (world.rand.nextFloat() - .5f);
|
||||||
|
plane = plane.scale(distance);
|
||||||
|
ItemStack stack = new ItemStack(Items.SLIME_BALL);
|
||||||
|
|
||||||
|
for (int i = fullBlock ? 40 : 15; i > 0; i--) {
|
||||||
|
Vec3d offset = VecHelper.rotate(plane, 360 * world.rand.nextFloat(), direction.getAxis());
|
||||||
|
Vec3d motion = offset.normalize().scale(1 / 16f);
|
||||||
|
if (fullBlock)
|
||||||
|
offset = new Vec3d(MathHelper.clamp(offset.x, -.5, .5), MathHelper.clamp(offset.y, -.5, .5),
|
||||||
|
MathHelper.clamp(offset.z, -.5, .5));
|
||||||
|
Vec3d particlePos = facePos.add(offset);
|
||||||
|
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), particlePos.x, particlePos.y,
|
||||||
|
particlePos.z, motion.x, motion.y, motion.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.config.AllConfigs;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public class SuperGlueRenderer extends EntityRenderer<SuperGlueEntity> {
|
||||||
|
|
||||||
|
private ResourceLocation regular = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png");
|
||||||
|
private ResourceLocation ghostly = new ResourceLocation(Create.ID, "textures/entity/super_glue/ghostly.png");
|
||||||
|
|
||||||
|
private Vec3d[] quad1;
|
||||||
|
private Vec3d[] quad2;
|
||||||
|
|
||||||
|
public SuperGlueRenderer(EntityRendererManager renderManager) {
|
||||||
|
super(renderManager);
|
||||||
|
initQuads();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getEntityTexture(SuperGlueEntity entity) {
|
||||||
|
return isVisible(entity) ? regular : ghostly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // TODO what are these floats for?
|
||||||
|
public void render(SuperGlueEntity entity, float p_225623_2_, float p_225623_3_, MatrixStack ms,
|
||||||
|
IRenderTypeBuffer buffer, int light) {
|
||||||
|
super.render(entity, p_225623_2_, p_225623_3_, ms, buffer, light);
|
||||||
|
IVertexBuilder builder = buffer.getBuffer(RenderType.getEntityCutout(getEntityTexture(entity)));
|
||||||
|
|
||||||
|
PlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
boolean visible = isVisible(entity);
|
||||||
|
boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand())
|
||||||
|
|| AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand());
|
||||||
|
holdingGlue = holdingGlue && AllConfigs.CLIENT.showHiddenSuperGlue.get();
|
||||||
|
|
||||||
|
if (!visible && !holdingGlue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// GlStateManager.pushMatrix(); TODO find equivalent
|
||||||
|
// GlStateManager.translated(x, y, z);
|
||||||
|
// GlStateManager.rotated(AngleHelper.horizontalAngle(facing), 0, 1, 0);
|
||||||
|
// GlStateManager.rotated(AngleHelper.verticalAngle(facing), 1, 0, 0);
|
||||||
|
// if (!visible) {
|
||||||
|
// GlStateManager.color4f(1, 1, 1, 0.375f);
|
||||||
|
// GlStateManager.enableBlend();
|
||||||
|
// GlStateManager.disableDepthTest();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO use quad1 & quad2 to render the glue texture
|
||||||
|
|
||||||
|
// GlStateManager.disableBlend();
|
||||||
|
// GlStateManager.enableDepthTest();
|
||||||
|
// GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
// GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVisible(SuperGlueEntity entity) {
|
||||||
|
if (!entity.isAlive())
|
||||||
|
return false;
|
||||||
|
BlockPos pos = entity.hangingPosition;
|
||||||
|
BlockPos pos2 = pos.offset(entity.getFacingDirection().getOpposite());
|
||||||
|
return entity.world.isAirBlock(pos) != entity.world.isAirBlock(pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initQuads() {
|
||||||
|
Vec3d diff = new Vec3d(Direction.SOUTH.getDirectionVec());
|
||||||
|
Vec3d extension = diff.normalize().scale(1 / 32f - 1 / 128f);
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(diff);
|
||||||
|
Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis();
|
||||||
|
|
||||||
|
Vec3d start = Vec3d.ZERO.subtract(extension);
|
||||||
|
Vec3d end = Vec3d.ZERO.add(extension);
|
||||||
|
|
||||||
|
plane = plane.scale(1 / 2f);
|
||||||
|
Vec3d a1 = plane.add(start);
|
||||||
|
Vec3d b1 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a2 = plane.add(start);
|
||||||
|
Vec3d b2 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a3 = plane.add(start);
|
||||||
|
Vec3d b3 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a4 = plane.add(start);
|
||||||
|
Vec3d b4 = plane.add(end);
|
||||||
|
|
||||||
|
quad1 = new Vec3d[] { a1, a2, a3, a4 };
|
||||||
|
quad2 = new Vec3d[] { b1, b2, b3, b4 };
|
||||||
|
|
||||||
|
// PositionTextureVertex v11 = new PositionTextureVertex(a1, 1, 0);
|
||||||
|
// PositionTextureVertex v12 = new PositionTextureVertex(a2, 1, 1);
|
||||||
|
// PositionTextureVertex v13 = new PositionTextureVertex(a3, 0, 1);
|
||||||
|
// PositionTextureVertex v14 = new PositionTextureVertex(a4, 0, 0);
|
||||||
|
//
|
||||||
|
// PositionTextureVertex v21 = new PositionTextureVertex(b1, 1, 0);
|
||||||
|
// PositionTextureVertex v22 = new PositionTextureVertex(b2, 1, 1);
|
||||||
|
// PositionTextureVertex v23 = new PositionTextureVertex(b3, 0, 1);
|
||||||
|
// PositionTextureVertex v24 = new PositionTextureVertex(b4, 0, 0);
|
||||||
|
//
|
||||||
|
// quad1 = new TexturedQuad(new PositionTextureVertex[] { v14, v11, v12, v13 }, 0, 0, 16, 16, 16, 16);
|
||||||
|
// quad2 = new TexturedQuad(new PositionTextureVertex[] { v21, v24, v23, v22 }, 0, 0, 16, 16, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
|
package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||||
import com.simibubi.create.foundation.utility.AllShapes;
|
import com.simibubi.create.foundation.utility.AllShapes;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractRailBlock;
|
import net.minecraft.block.AbstractRailBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
@ -12,13 +13,16 @@ import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.material.PushReaction;
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.EnumProperty;
|
import net.minecraft.state.EnumProperty;
|
||||||
import net.minecraft.state.IProperty;
|
import net.minecraft.state.IProperty;
|
||||||
import net.minecraft.state.StateContainer.Builder;
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.state.properties.RailShape;
|
import net.minecraft.state.properties.RailShape;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -28,7 +32,7 @@ import net.minecraft.util.math.shapes.VoxelShapes;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CartAssemblerBlock extends AbstractRailBlock {
|
public class CartAssemblerBlock extends AbstractRailBlock implements ITE<CartAssemblerTileEntity> {
|
||||||
|
|
||||||
public static IProperty<RailShape> RAIL_SHAPE =
|
public static IProperty<RailShape> RAIL_SHAPE =
|
||||||
EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH);
|
EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH);
|
||||||
|
@ -45,6 +49,16 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
super.fillStateContainer(builder);
|
super.fillStateContainer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTileEntity(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
|
return new CartAssemblerTileEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||||
boolean alongX = context.getPlacementHorizontalFacing().getAxis() == Axis.X;
|
boolean alongX = context.getPlacementHorizontalFacing().getAxis() == Axis.X;
|
||||||
|
@ -60,7 +74,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMinecartPass(BlockState state, World world, BlockPos pos, AbstractMinecartEntity cart) {
|
public void onMinecartPass(BlockState state, World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||||
if (!cart.canBeRidden())
|
if (!cart.canBeRidden() && !(cart instanceof FurnaceMinecartEntity))
|
||||||
return;
|
return;
|
||||||
if (state.get(POWERED))
|
if (state.get(POWERED))
|
||||||
disassemble(world, pos, cart);
|
disassemble(world, pos, cart);
|
||||||
|
@ -72,16 +86,28 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
if (!cart.getPassengers().isEmpty())
|
if (!cart.getPassengers().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Contraption contraption = MountedContraption.assembleMinecart(world, pos);
|
MountedContraption contraption = MountedContraption.assembleMinecart(world, pos);
|
||||||
if (contraption == null)
|
if (contraption == null)
|
||||||
return;
|
return;
|
||||||
if (contraption.blocks.size() == 1)
|
if (contraption.blocks.size() == 1)
|
||||||
return;
|
return;
|
||||||
float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion());
|
|
||||||
|
int yawFromVector = (int) (ContraptionEntity.yawFromVector(cart.getMotion()) + .5d);
|
||||||
|
yawFromVector = ((yawFromVector + 45) / 90) * 90;
|
||||||
|
float initialAngle = yawFromVector;
|
||||||
|
|
||||||
|
withTileEntityDo(world, pos, te -> contraption.rotationMode = CartMovementMode.values()[te.movementMode.value]);
|
||||||
ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle);
|
ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle);
|
||||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||||
world.addEntity(entity);
|
world.addEntity(entity);
|
||||||
entity.startRiding(cart);
|
entity.startRiding(cart);
|
||||||
|
|
||||||
|
if (cart instanceof FurnaceMinecartEntity) {
|
||||||
|
CompoundNBT nbt = cart.serializeNBT();
|
||||||
|
nbt.putDouble("PushZ", 0);
|
||||||
|
nbt.putDouble("PushX", 0);
|
||||||
|
cart.deserializeNBT(nbt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||||
|
@ -90,6 +116,13 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
if (!(cart.getPassengers().get(0) instanceof ContraptionEntity))
|
if (!(cart.getPassengers().get(0) instanceof ContraptionEntity))
|
||||||
return;
|
return;
|
||||||
cart.removePassengers();
|
cart.removePassengers();
|
||||||
|
|
||||||
|
if (cart instanceof FurnaceMinecartEntity) {
|
||||||
|
CompoundNBT nbt = cart.serializeNBT();
|
||||||
|
nbt.putDouble("PushZ", cart.getMotion().x);
|
||||||
|
nbt.putDouble("PushX", cart.getMotion().z);
|
||||||
|
cart.deserializeNBT(nbt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,6 +175,13 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
builder.add(BlockStateProperties.HORIZONTAL_AXIS);
|
builder.add(BlockStateProperties.HORIZONTAL_AXIS);
|
||||||
super.fillStateContainer(builder);
|
super.fillStateContainer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
||||||
|
ISelectionContext p_220053_4_) {
|
||||||
|
return VoxelShapes.empty();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockState createAnchor(BlockState state) {
|
public static BlockState createAnchor(BlockState state) {
|
||||||
|
@ -149,4 +189,9 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||||
return AllBlocks.MINECART_ANCHOR.get().getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis);
|
return AllBlocks.MINECART_ANCHOR.get().getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<CartAssemblerTileEntity> getTileEntityClass() {
|
||||||
|
return CartAssemblerTileEntity.class;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.ScreenResources;
|
||||||
|
import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform;
|
||||||
|
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions;
|
||||||
|
import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
|
||||||
|
public class CartAssemblerTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
|
protected ScrollOptionBehaviour<CartMovementMode> movementMode;
|
||||||
|
|
||||||
|
public CartAssemblerTileEntity() {
|
||||||
|
super(AllTileEntities.CART_ASSEMBLER.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
movementMode = new ScrollOptionBehaviour<>(CartMovementMode.class,
|
||||||
|
Lang.translate("contraptions.cart_movement_mode"), this, getMovementModeSlot());
|
||||||
|
movementMode.requiresWrench();
|
||||||
|
behaviours.add(movementMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ValueBoxTransform getMovementModeSlot() {
|
||||||
|
return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum CartMovementMode implements INamedIconOptions {
|
||||||
|
|
||||||
|
ROTATE(ScreenResources.I_CART_ROTATE),
|
||||||
|
ROTATE_PAUSED(ScreenResources.I_CART_ROTATE_PAUSED),
|
||||||
|
ROTATION_LOCKED(ScreenResources.I_CART_ROTATE_LOCKED),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private String translationKey;
|
||||||
|
private ScreenResources icon;
|
||||||
|
|
||||||
|
private CartMovementMode(ScreenResources icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
translationKey = "contraptions.cart_movement_mode." + Lang.asId(name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreenResources getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey() {
|
||||||
|
return translationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.mounted;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
|
|
||||||
|
import net.minecraft.block.AbstractRailBlock;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.DispenserBlock;
|
||||||
|
import net.minecraft.dispenser.DefaultDispenseItemBehavior;
|
||||||
|
import net.minecraft.dispenser.IBlockSource;
|
||||||
|
import net.minecraft.dispenser.IDispenseItemBehavior;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity.Type;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.state.properties.RailShape;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
|
||||||
|
@EventBusSubscriber
|
||||||
|
public class MinecartContraptionItem extends Item {
|
||||||
|
|
||||||
|
private final AbstractMinecartEntity.Type minecartType;
|
||||||
|
|
||||||
|
public MinecartContraptionItem(Type minecartTypeIn, Properties builder) {
|
||||||
|
super(builder);
|
||||||
|
this.minecartType = minecartTypeIn;
|
||||||
|
DispenserBlock.registerDispenseBehavior(this, DISPENSER_BEHAVIOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taken and adjusted from MinecartItem
|
||||||
|
private static final IDispenseItemBehavior DISPENSER_BEHAVIOR = new DefaultDispenseItemBehavior() {
|
||||||
|
private final DefaultDispenseItemBehavior behaviourDefaultDispenseItem = new DefaultDispenseItemBehavior();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
|
||||||
|
Direction direction = source.getBlockState().get(DispenserBlock.FACING);
|
||||||
|
World world = source.getWorld();
|
||||||
|
double d0 = source.getX() + (double) direction.getXOffset() * 1.125D;
|
||||||
|
double d1 = Math.floor(source.getY()) + (double) direction.getYOffset();
|
||||||
|
double d2 = source.getZ() + (double) direction.getZOffset() * 1.125D;
|
||||||
|
BlockPos blockpos = source.getBlockPos().offset(direction);
|
||||||
|
BlockState blockstate = world.getBlockState(blockpos);
|
||||||
|
RailShape railshape = blockstate.getBlock() instanceof AbstractRailBlock
|
||||||
|
? ((AbstractRailBlock) blockstate.getBlock()).getRailDirection(blockstate, world, blockpos, null)
|
||||||
|
: RailShape.NORTH_SOUTH;
|
||||||
|
double d3;
|
||||||
|
if (blockstate.isIn(BlockTags.RAILS)) {
|
||||||
|
if (railshape.isAscending()) {
|
||||||
|
d3 = 0.6D;
|
||||||
|
} else {
|
||||||
|
d3 = 0.1D;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!blockstate.isAir(world, blockpos) || !world.getBlockState(blockpos.down()).isIn(BlockTags.RAILS)) {
|
||||||
|
return this.behaviourDefaultDispenseItem.dispense(source, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockState blockstate1 = world.getBlockState(blockpos.down());
|
||||||
|
RailShape railshape1 = blockstate1.getBlock() instanceof AbstractRailBlock
|
||||||
|
? ((AbstractRailBlock) blockstate1.getBlock()).getRailDirection(blockstate1, world,
|
||||||
|
blockpos.down(), null)
|
||||||
|
: RailShape.NORTH_SOUTH;
|
||||||
|
if (direction != Direction.DOWN && railshape1.isAscending()) {
|
||||||
|
d3 = -0.4D;
|
||||||
|
} else {
|
||||||
|
d3 = -0.9D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractMinecartEntity abstractminecartentity = AbstractMinecartEntity.create(world, d0, d1 + d3, d2,
|
||||||
|
((MinecartContraptionItem) stack.getItem()).minecartType);
|
||||||
|
if (stack.hasDisplayName())
|
||||||
|
abstractminecartentity.setCustomName(stack.getDisplayName());
|
||||||
|
world.addEntity(abstractminecartentity);
|
||||||
|
addContraptionToMinecart(world, stack, abstractminecartentity, direction);
|
||||||
|
|
||||||
|
stack.shrink(1);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void playDispenseSound(IBlockSource source) {
|
||||||
|
source.getWorld().playEvent(1000, source.getBlockPos(), 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Taken and adjusted from MinecartItem
|
||||||
|
@Override
|
||||||
|
public ActionResultType onItemUse(ItemUseContext context) {
|
||||||
|
World world = context.getWorld();
|
||||||
|
BlockPos blockpos = context.getPos();
|
||||||
|
BlockState blockstate = world.getBlockState(blockpos);
|
||||||
|
if (!blockstate.isIn(BlockTags.RAILS)) {
|
||||||
|
return ActionResultType.FAIL;
|
||||||
|
} else {
|
||||||
|
ItemStack itemstack = context.getItem();
|
||||||
|
if (!world.isRemote) {
|
||||||
|
RailShape railshape = blockstate.getBlock() instanceof AbstractRailBlock
|
||||||
|
? ((AbstractRailBlock) blockstate.getBlock()).getRailDirection(blockstate, world, blockpos,
|
||||||
|
null)
|
||||||
|
: RailShape.NORTH_SOUTH;
|
||||||
|
double d0 = 0.0D;
|
||||||
|
if (railshape.isAscending()) {
|
||||||
|
d0 = 0.5D;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractMinecartEntity abstractminecartentity = AbstractMinecartEntity.create(world,
|
||||||
|
(double) blockpos.getX() + 0.5D, (double) blockpos.getY() + 0.0625D + d0,
|
||||||
|
(double) blockpos.getZ() + 0.5D, this.minecartType);
|
||||||
|
if (itemstack.hasDisplayName())
|
||||||
|
abstractminecartentity.setCustomName(itemstack.getDisplayName());
|
||||||
|
PlayerEntity player = context.getPlayer();
|
||||||
|
world.addEntity(abstractminecartentity);
|
||||||
|
addContraptionToMinecart(world, itemstack, abstractminecartentity,
|
||||||
|
player == null ? null : player.getHorizontalFacing());
|
||||||
|
}
|
||||||
|
|
||||||
|
itemstack.shrink(1);
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addContraptionToMinecart(World world, ItemStack itemstack, AbstractMinecartEntity cart,
|
||||||
|
@Nullable Direction newFacing) {
|
||||||
|
CompoundNBT tag = itemstack.getOrCreateTag();
|
||||||
|
if (tag.contains("Contraption")) {
|
||||||
|
CompoundNBT contraptionTag = tag.getCompound("Contraption");
|
||||||
|
float initialAngle = contraptionTag.getFloat("InitialAngle");
|
||||||
|
Contraption mountedContraption = Contraption.fromNBT(world, contraptionTag);
|
||||||
|
ContraptionEntity contraption;
|
||||||
|
|
||||||
|
if (newFacing != null)
|
||||||
|
contraption = ContraptionEntity.createMounted(world, mountedContraption, initialAngle, newFacing);
|
||||||
|
else
|
||||||
|
contraption = ContraptionEntity.createMounted(world, mountedContraption, initialAngle);
|
||||||
|
|
||||||
|
contraption.startRiding(cart);
|
||||||
|
contraption.setPosition(cart.getX(), cart.getY(), cart.getZ());
|
||||||
|
world.addEntity(contraption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey(ItemStack stack) {
|
||||||
|
return "item.create.minecart_contraption";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void wrenchCanBeUsedToPickUpMinecartContraptions(PlayerInteractEvent.EntityInteract event) {
|
||||||
|
Entity entity = event.getTarget();
|
||||||
|
PlayerEntity player = event.getPlayer();
|
||||||
|
if (player == null || entity == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack wrench = player.getHeldItem(event.getHand());
|
||||||
|
if (!AllItems.WRENCH.typeOf(wrench))
|
||||||
|
return;
|
||||||
|
if (entity instanceof ContraptionEntity)
|
||||||
|
entity = entity.getRidingEntity();
|
||||||
|
if (!(entity instanceof AbstractMinecartEntity))
|
||||||
|
return;
|
||||||
|
AbstractMinecartEntity cart = (AbstractMinecartEntity) entity;
|
||||||
|
Type type = cart.getMinecartType();
|
||||||
|
if (type != Type.RIDEABLE && type != Type.FURNACE)
|
||||||
|
return;
|
||||||
|
List<Entity> passengers = cart.getPassengers();
|
||||||
|
if (passengers.isEmpty() || !(passengers.get(0) instanceof ContraptionEntity))
|
||||||
|
return;
|
||||||
|
ContraptionEntity contraption = (ContraptionEntity) passengers.get(0);
|
||||||
|
|
||||||
|
if (!event.getWorld().isRemote) {
|
||||||
|
player.inventory.placeItemBackInInventory(event.getWorld(), create(type, contraption));
|
||||||
|
contraption.remove();
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||||
|
event.setCanceled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack create(Type type, ContraptionEntity entity) {
|
||||||
|
ItemStack stack =
|
||||||
|
(type == Type.RIDEABLE ? AllItems.MINECART_CONTRAPTION : AllItems.FURNACE_MINECART_CONTRAPTION).asStack();
|
||||||
|
CompoundNBT tag = entity.getContraption().writeNBT();
|
||||||
|
tag.remove("UUID");
|
||||||
|
tag.remove("Pos");
|
||||||
|
tag.remove("Motion");
|
||||||
|
tag.putFloat("InitialAngle", entity.getInitialAngle());
|
||||||
|
stack.getOrCreateTag().put("Contraption", tag);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,10 +7,14 @@ import java.util.List;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes;
|
import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.state.properties.RailShape;
|
import net.minecraft.state.properties.RailShape;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -25,12 +29,14 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
|
||||||
public class MountedContraption extends Contraption {
|
public class MountedContraption extends Contraption {
|
||||||
|
|
||||||
|
public CartMovementMode rotationMode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AllContraptionTypes getType() {
|
protected AllContraptionTypes getType() {
|
||||||
return AllContraptionTypes.MOUNTED;
|
return AllContraptionTypes.MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Contraption assembleMinecart(World world, BlockPos pos) {
|
public static MountedContraption assembleMinecart(World world, BlockPos pos) {
|
||||||
if (isFrozen())
|
if (isFrozen())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -38,7 +44,7 @@ public class MountedContraption extends Contraption {
|
||||||
if (!state.has(RAIL_SHAPE))
|
if (!state.has(RAIL_SHAPE))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Contraption contraption = new MountedContraption();
|
MountedContraption contraption = new MountedContraption();
|
||||||
if (!contraption.searchMovedStructure(world, pos, null))
|
if (!contraption.searchMovedStructure(world, pos, null))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -61,8 +67,14 @@ public class MountedContraption extends Contraption {
|
||||||
if (!AllBlocks.CART_ASSEMBLER.typeOf(state))
|
if (!AllBlocks.CART_ASSEMBLER.typeOf(state))
|
||||||
return false;
|
return false;
|
||||||
Axis axis = state.get(CartAssemblerBlock.RAIL_SHAPE) == RailShape.EAST_WEST ? Axis.Z : Axis.X;
|
Axis axis = state.get(CartAssemblerBlock.RAIL_SHAPE) == RailShape.EAST_WEST ? Axis.Z : Axis.X;
|
||||||
for (AxisDirection axisDirection : AxisDirection.values())
|
for (AxisDirection axisDirection : AxisDirection.values()) {
|
||||||
frontier.add(pos.offset(Direction.getFacingFromAxis(axisDirection, axis)));
|
Direction facingFromAxis = Direction.getFacingFromAxis(axisDirection, axis);
|
||||||
|
BlockPos offset = pos.offset(facingFromAxis);
|
||||||
|
BlockState blockState = world.getBlockState(offset);
|
||||||
|
if (!BlockMovementTraits.isBrittle(blockState)
|
||||||
|
|| BlockMovementTraits.isBlockAttachedTowards(blockState, facingFromAxis.getOpposite()))
|
||||||
|
frontier.add(offset);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,14 +88,27 @@ public class MountedContraption extends Contraption {
|
||||||
return pair;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT writeNBT() {
|
||||||
|
CompoundNBT writeNBT = super.writeNBT();
|
||||||
|
writeNBT.putString("RotationMode", NBTHelper.writeEnum(rotationMode));
|
||||||
|
return writeNBT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNBT(World world, CompoundNBT nbt) {
|
||||||
|
rotationMode = NBTHelper.readEnum(nbt.getString("RotationMode"), CartMovementMode.class);
|
||||||
|
super.readNBT(world, nbt);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
||||||
super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor));
|
super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
super.disassemble(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,8 +293,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
|
||||||
@Override
|
@Override
|
||||||
public void attach(ContraptionEntity contraption) {
|
public void attach(ContraptionEntity contraption) {
|
||||||
this.movedContraption = contraption;
|
this.movedContraption = contraption;
|
||||||
if (!world.isRemote)
|
if (!world.isRemote) {
|
||||||
|
this.running = true;
|
||||||
sendData();
|
sendData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,6 +42,9 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void assemble() {
|
public void assemble() {
|
||||||
|
if (!(world.getBlockState(pos).getBlock() instanceof MechanicalPistonBlock))
|
||||||
|
return;
|
||||||
|
|
||||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||||
|
|
||||||
// Collect Construct
|
// Collect Construct
|
||||||
|
@ -83,10 +86,11 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (!running)
|
if (!running && movedContraption == null)
|
||||||
return;
|
return;
|
||||||
if (!removed)
|
if (!removed)
|
||||||
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
|
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED),
|
||||||
|
3 | 16);
|
||||||
if (movedContraption != null) {
|
if (movedContraption != null) {
|
||||||
applyContraptionPosition();
|
applyContraptionPosition();
|
||||||
movedContraption.disassemble();
|
movedContraption.disassemble();
|
||||||
|
|
|
@ -6,7 +6,6 @@ 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 net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.config.AllConfigs;
|
import com.simibubi.create.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes;
|
import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits;
|
import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -63,17 +65,24 @@ public class PistonContraption extends Contraption {
|
||||||
BlockPos actualStart = pos;
|
BlockPos actualStart = pos;
|
||||||
BlockState nextBlock = world.getBlockState(actualStart.offset(direction));
|
BlockState nextBlock = world.getBlockState(actualStart.offset(direction));
|
||||||
int extensionsInFront = 0;
|
int extensionsInFront = 0;
|
||||||
boolean sticky = STICKY_MECHANICAL_PISTON.typeOf(world.getBlockState(pos));
|
BlockState blockState = world.getBlockState(pos);
|
||||||
|
boolean sticky = STICKY_MECHANICAL_PISTON.typeOf(blockState);
|
||||||
|
|
||||||
if (world.getBlockState(pos).get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) {
|
if (!(blockState.getBlock() instanceof MechanicalPistonBlock))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) {
|
||||||
while (PISTON_POLE.typeOf(nextBlock) && nextBlock.get(FACING).getAxis() == direction.getAxis()
|
while (PISTON_POLE.typeOf(nextBlock) && nextBlock.get(FACING).getAxis() == direction.getAxis()
|
||||||
|| MECHANICAL_PISTON_HEAD.typeOf(nextBlock) && nextBlock.get(FACING) == direction) {
|
|| MECHANICAL_PISTON_HEAD.typeOf(nextBlock) && nextBlock.get(FACING) == direction) {
|
||||||
|
|
||||||
actualStart = actualStart.offset(direction);
|
actualStart = actualStart.offset(direction);
|
||||||
poles.add(new BlockInfo(actualStart, nextBlock.with(FACING, direction), null));
|
poles.add(new BlockInfo(actualStart, nextBlock.with(FACING, direction), null));
|
||||||
extensionsInFront++;
|
extensionsInFront++;
|
||||||
nextBlock = world.getBlockState(actualStart.offset(direction));
|
|
||||||
|
|
||||||
|
if (MECHANICAL_PISTON_HEAD.typeOf(nextBlock))
|
||||||
|
break;
|
||||||
|
|
||||||
|
nextBlock = world.getBlockState(actualStart.offset(direction));
|
||||||
if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles())
|
if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +131,11 @@ public class PistonContraption extends Contraption {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||||
|
return pistonExtensionCollisionBox.contains(VecHelper.getCenterOf(pos.subtract(anchor)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List<BlockPos> frontier) {
|
protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List<BlockPos> frontier) {
|
||||||
frontier.clear();
|
frontier.clear();
|
||||||
|
@ -138,6 +152,8 @@ public class PistonContraption extends Contraption {
|
||||||
if (!BlockMovementTraits.movementNecessary(world, currentPos))
|
if (!BlockMovementTraits.movementNecessary(world, currentPos))
|
||||||
return true;
|
return true;
|
||||||
BlockState state = world.getBlockState(currentPos);
|
BlockState state = world.getBlockState(currentPos);
|
||||||
|
if (BlockMovementTraits.isBrittle(state))
|
||||||
|
return true;
|
||||||
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite())
|
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite())
|
||||||
return true;
|
return true;
|
||||||
if (!BlockMovementTraits.movementAllowed(world, currentPos))
|
if (!BlockMovementTraits.movementAllowed(world, currentPos))
|
||||||
|
@ -146,7 +162,7 @@ public class PistonContraption extends Contraption {
|
||||||
if (BlockMovementTraits.notSupportive(state, orientation))
|
if (BlockMovementTraits.notSupportive(state, orientation))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false; // too many
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -155,8 +171,17 @@ public class PistonContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
public void addGlue(SuperGlueEntity entity) {
|
||||||
super.disassemble(world, offset, rotation, (pos, state) -> {
|
BlockPos pos = entity.getHangingPosition();
|
||||||
|
Direction direction = entity.getFacingDirection();
|
||||||
|
BlockPos localPos = pos.subtract(anchor).offset(orientation, -initialExtensionProgress);
|
||||||
|
this.superglue.add(Pair.of(localPos, direction));
|
||||||
|
glueToRemove.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
|
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> {
|
||||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||||
BlockState pistonState = world.getBlockState(pistonPos);
|
BlockState pistonState = world.getBlockState(pistonPos);
|
||||||
TileEntity te = world.getTileEntity(pistonPos);
|
TileEntity te = world.getTileEntity(pistonPos);
|
||||||
|
@ -165,7 +190,7 @@ public class PistonContraption extends Contraption {
|
||||||
return true;
|
return true;
|
||||||
if (!AllBlocks.PISTON_POLE.typeOf(state) && pistonState.getBlock() instanceof MechanicalPistonBlock)
|
if (!AllBlocks.PISTON_POLE.typeOf(state) && pistonState.getBlock() instanceof MechanicalPistonBlock)
|
||||||
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
|
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
|
||||||
3);
|
3 | 16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -178,7 +203,7 @@ public class PistonContraption extends Contraption {
|
||||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||||
BlockState blockState = world.getBlockState(pos);
|
BlockState blockState = world.getBlockState(pos);
|
||||||
if (pos.equals(pistonPos) && blockState.getBlock() instanceof MechanicalPistonBlock) {
|
if (pos.equals(pistonPos) && blockState.getBlock() instanceof MechanicalPistonBlock) {
|
||||||
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
|
world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.simibubi.create.modules.contraptions.components.contraptions.pulley;
|
package com.simibubi.create.modules.contraptions.components.contraptions.pulley;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
import com.simibubi.create.foundation.utility.AllShapes;
|
import com.simibubi.create.foundation.utility.AllShapes;
|
||||||
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
|
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
|
||||||
|
@ -8,6 +7,7 @@ import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.state.EnumProperty;
|
import net.minecraft.state.EnumProperty;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
@ -42,6 +42,17 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
|
if (!worldIn.isRemote) {
|
||||||
|
BlockState below = worldIn.getBlockState(pos.down());
|
||||||
|
if (below.getBlock() instanceof RopeBlockBase)
|
||||||
|
worldIn.destroyBlock(pos.down(), true);
|
||||||
|
}
|
||||||
|
worldIn.removeTileEntity(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
if (!player.isAllowEdit())
|
if (!player.isAllowEdit())
|
||||||
|
@ -76,27 +87,23 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
boolean isMoving) {
|
return PushReaction.BLOCK;
|
||||||
if (isMoving)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fromPos.equals(pos.down()) && this != AllBlocks.PULLEY_MAGNET.get())
|
|
||||||
if (!AllBlocks.ROPE.typeOf(worldIn.getBlockState(fromPos))
|
|
||||||
&& !AllBlocks.PULLEY_MAGNET.typeOf(worldIn.getBlockState(fromPos))) {
|
|
||||||
worldIn.destroyBlock(pos, true);
|
|
||||||
}
|
|
||||||
if (fromPos.equals(pos.up()))
|
|
||||||
if (!AllBlocks.ROPE.typeOf(worldIn.getBlockState(fromPos))
|
|
||||||
&& !AllBlocks.ROPE_PULLEY.typeOf(worldIn.getBlockState(fromPos))) {
|
|
||||||
worldIn.destroyBlock(pos, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
if (!isMoving)
|
if (!isMoving) {
|
||||||
onRopeBroken(worldIn, pos.up());
|
onRopeBroken(worldIn, pos.up());
|
||||||
|
if (!worldIn.isRemote) {
|
||||||
|
BlockState above = worldIn.getBlockState(pos.up());
|
||||||
|
BlockState below = worldIn.getBlockState(pos.down());
|
||||||
|
if (above.getBlock() instanceof RopeBlockBase)
|
||||||
|
worldIn.destroyBlock(pos.up(), true);
|
||||||
|
if (below.getBlock() instanceof RopeBlockBase)
|
||||||
|
worldIn.destroyBlock(pos.down(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,16 @@ public class PulleyContraption extends Contraption {
|
||||||
return construct;
|
return construct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isAnchoringBlockAt(BlockPos pos) {
|
||||||
|
if (pos.getX() != anchor.getX() || pos.getZ() != anchor.getZ())
|
||||||
|
return false;
|
||||||
|
int y = pos.getY();
|
||||||
|
if (y <= anchor.getY() || y > anchor.getY() + initialOffset + 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT writeNBT() {
|
public CompoundNBT writeNBT() {
|
||||||
CompoundNBT writeNBT = super.writeNBT();
|
CompoundNBT writeNBT = super.writeNBT();
|
||||||
|
|
|
@ -37,6 +37,8 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assemble() {
|
protected void assemble() {
|
||||||
|
if (!(world.getBlockState(pos).getBlock() instanceof PulleyBlock))
|
||||||
|
return;
|
||||||
if (speed == 0)
|
if (speed == 0)
|
||||||
return;
|
return;
|
||||||
if (offset >= getExtensionRange() && getSpeed() > 0)
|
if (offset >= getExtensionRange() && getSpeed() > 0)
|
||||||
|
@ -81,7 +83,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble() {
|
public void disassemble() {
|
||||||
if (!running)
|
if (!running && movedContraption == null)
|
||||||
return;
|
return;
|
||||||
offset = getGridOffset(offset);
|
offset = getGridOffset(offset);
|
||||||
if (movedContraption != null)
|
if (movedContraption != null)
|
||||||
|
@ -137,6 +139,8 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||||
BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1);
|
BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1);
|
||||||
if (!BlockMovementTraits.movementNecessary(world, posBelow))
|
if (!BlockMovementTraits.movementNecessary(world, posBelow))
|
||||||
return;
|
return;
|
||||||
|
if (BlockMovementTraits.isBrittle(world.getBlockState(posBelow)))
|
||||||
|
return;
|
||||||
|
|
||||||
disassemble();
|
disassemble();
|
||||||
assembleNextTick = true;
|
assembleNextTick = true;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static com.simibubi.create.modules.contraptions.base.HorizontalKineticBlo
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -137,8 +138,8 @@ public class ConnectedInputHandler {
|
||||||
if (controllerPos1.equals(controllerPos2)) {
|
if (controllerPos1.equals(controllerPos2)) {
|
||||||
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
||||||
|
|
||||||
Set<BlockPos> positions = controller.input.data.stream().map(l -> controllerPos1.add(l))
|
Set<BlockPos> positions =
|
||||||
.collect(Collectors.toSet());
|
controller.input.data.stream().map(l -> controllerPos1.add(l)).collect(Collectors.toSet());
|
||||||
List<BlockPos> frontier = new LinkedList<>();
|
List<BlockPos> frontier = new LinkedList<>();
|
||||||
List<BlockPos> splitGroup = new ArrayList<>();
|
List<BlockPos> splitGroup = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -198,8 +199,7 @@ public class ConnectedInputHandler {
|
||||||
|
|
||||||
crafter1.input.data.forEach(offset -> {
|
crafter1.input.data.forEach(offset -> {
|
||||||
BlockPos connectedPos = crafter1.getPos().add(offset);
|
BlockPos connectedPos = crafter1.getPos().add(offset);
|
||||||
modifyAndUpdate(world, connectedPos, input -> {
|
modifyAndUpdate(world, connectedPos, input -> {});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
crafter2.input.data.forEach(offset -> {
|
crafter2.input.data.forEach(offset -> {
|
||||||
|
@ -229,7 +229,7 @@ public class ConnectedInputHandler {
|
||||||
|
|
||||||
public static class ConnectedInput {
|
public static class ConnectedInput {
|
||||||
boolean isController;
|
boolean isController;
|
||||||
List<BlockPos> data = new ArrayList<>();
|
List<BlockPos> data = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
public ConnectedInput() {
|
public ConnectedInput() {
|
||||||
isController = true;
|
isController = true;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCra
|
||||||
import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -357,8 +358,10 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void eject() {
|
public void eject() {
|
||||||
Vec3d ejectPos = VecHelper.getCenterOf(pos)
|
BlockState blockState = getBlockState();
|
||||||
.add(new Vec3d(getBlockState().get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f));
|
boolean present = AllBlocks.MECHANICAL_CRAFTER.typeOf(blockState);
|
||||||
|
Vec3d vec = present ? new Vec3d(blockState.get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f) : Vec3d.ZERO;
|
||||||
|
Vec3d ejectPos = VecHelper.getCenterOf(pos).add(vec);
|
||||||
groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack));
|
groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack));
|
||||||
if (!inventory.getStackInSlot(0).isEmpty())
|
if (!inventory.getStackInSlot(0).isEmpty())
|
||||||
dropItem(ejectPos, inventory.getStackInSlot(0));
|
dropItem(ejectPos, inventory.getStackInSlot(0));
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue