Bugs & Refactors

- Added new selection/outline particles for use in place of bounding box rendering
- Refactored JEI categories
- Slots for chance outputs now have a slighly different appearance in JEI
- Redstone links no longer cause a redstone update when loaded in
- Redstone links no longer mess up windmill bearings on chunk reload
- Fixed redstone links not working properly after movement in a contraption
- Filter output amounts can no longer be increased beyond the stack limit
- Chassis range visualization now uses the new outline particle
- Kinetic networks are now aware of movement, such as NBT-item placement, schematic placement and other means of tileentity movement and will reset/reconnect
- Fixed pistons/bearings/etc not being movable by chassis
- Fixed pistons/bearings/etc moving a clone of themselves when attached to the initial block
- Fixed pistons/bearings/etc stopping or losing their structure when loaded incorrecly
- Pulleys can now be moved while extended, moving attached ropes and their own attached structure with them
- Brittle blocks such as ladders/torches/etc can no longer be moved unless their attached block is moved
- Fixed mechanical pistons messing up their kinetic information when changing into a different extension state.
- Fixed misplaced client code introduced by a ScreenOpener hotfix
- Fixed inconsistent belt initialization when belts are placed by schematics or structures, causing them to break at random
- Clutches and Gearshifts now await their turn to re-attach when changed, allowing multiple to be used in a network and swapped within one tick without causing components to break.
- Fixed flexcrate interface crashing if the block gets removed while open
- Some additions/modifications in texture assets
- Pistons no longer get blocked by their push limit if the blocks pushed are attached to each other
This commit is contained in:
simibubi 2020-04-16 20:46:15 +02:00
parent 7374866293
commit db8e52be2e
86 changed files with 1089 additions and 762 deletions

View file

@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = 'mc1.14.4_v0.2.2b' version = 'mc1.14.4_v0.2.3'
group = 'com.simibubi.create' group = 'com.simibubi.create'
archivesBaseName = 'create' archivesBaseName = 'create'

View file

@ -75,8 +75,8 @@ public enum AllItems {
ZINC_INGOT(new TaggedItem().withForgeTags("ingots/zinc")), ZINC_INGOT(new TaggedItem().withForgeTags("ingots/zinc")),
BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")), BRASS_INGOT(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,21 +86,17 @@ 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,
ANTIOXIDANT,
SAND_PAPER(SandPaperItem::new),
RED_SAND_PAPER(SandPaperItem::new),
WRENCH(WrenchItem::new), WRENCH(WrenchItem::new),
GOGGLES(GogglesItem::new), GOGGLES(GogglesItem::new),
@ -114,6 +110,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 +126,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 +199,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);
} }
@ -226,11 +229,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;
} }

View file

@ -8,6 +8,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT) @EventBusSubscriber(value = Dist.CLIENT)
public enum AllSpecialTextures { public enum AllSpecialTextures {
BLANK("blank.png"),
SELECTION("selection.png"), SELECTION("selection.png"),
; ;

View file

@ -41,7 +41,7 @@ public enum ScreenResources {
FILTER("filter.png", 200, 100), FILTER("filter.png", 200, 100),
ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86), ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86),
SEQUENCER("sequencer.png", 156, 128), SEQUENCER("sequencer.png", 156, 128),
SEQUENCER_INSTRUCTION("sequencer.png", 14, 47, 131, 18), SEQUENCER_INSTRUCTION("sequencer.png", 14, 47, 131, 18),
SEQUENCER_WAIT("sequencer.png", 14, 65, 131, 18), SEQUENCER_WAIT("sequencer.png", 14, 65, 131, 18),
@ -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),

View file

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

View file

@ -2,38 +2,18 @@ package com.simibubi.create.compat.jei.category;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
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);

View file

@ -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());

View file

@ -9,8 +9,6 @@ import java.util.stream.Collectors;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
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);
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translated(126, 0, 0); GlStateManager.translated(126, 0, 0);

View file

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

View file

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

View file

@ -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());

View file

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

View file

@ -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
@ -77,7 +50,7 @@ public class MixingCategory implements IRecipeCategory<MixingRecipe> {
NonNullList<Ingredient> recipeIngredients = recipe.getIngredients(); NonNullList<Ingredient> recipeIngredients = recipe.getIngredients();
List<Pair<Ingredient, MutableInt>> actualIngredients = ItemHelper.condenseIngredients(recipeIngredients); List<Pair<Ingredient, MutableInt>> actualIngredients = ItemHelper.condenseIngredients(recipeIngredients);
Map<Integer, Float> catalystIndices = new HashMap<>(9); Map<Integer, Float> catalystIndices = new HashMap<>(9);
for (int i = 0; i < actualIngredients.size(); i++) { for (int i = 0; i < actualIngredients.size(); i++) {
for (ProcessingIngredient processingIngredient : recipe.getRollableIngredients()) { for (ProcessingIngredient processingIngredient : recipe.getRollableIngredients()) {
@ -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;
}
} }

View file

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

View file

@ -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());

View file

@ -5,66 +5,35 @@ import java.util.List;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
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);

View file

@ -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());
@ -79,16 +46,16 @@ public class PressingCategory implements IRecipeCategory<PressingRecipe> {
itemStacks.init(outputIndex + 1, false, 131 + 19 * outputIndex, 50); itemStacks.init(outputIndex + 1, false, 131 + 19 * outputIndex, 50);
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);

View file

@ -6,7 +6,6 @@ import com.mojang.blaze3d.platform.GlStateManager;
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,22 +14,18 @@ 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
public void setIngredients(T recipe, IIngredients ingredients) { public void setIngredients(T recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients()); ingredients.setInputIngredients(recipe.getIngredients());

View file

@ -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());
@ -81,8 +48,8 @@ public class SawingCategory implements IRecipeCategory<CuttingRecipe> {
itemStacks.init(outputIndex + 1, false, 117 + xOffset, 47 + yOffset); itemStacks.init(outputIndex + 1, false, 117 + xOffset, 47 + yOffset);
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);

View file

@ -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());

View file

@ -5,52 +5,24 @@ import java.util.List;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
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);
} }
} }

View file

@ -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() {
}
}

View file

@ -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);
} }
@ -106,7 +107,7 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
public void lazyTick() { public void lazyTick() {
} }
protected void forEachBehaviour(Consumer<TileEntityBehaviour> action) { protected void forEachBehaviour(Consumer<TileEntityBehaviour> action) {
behaviours.values().forEach(tb -> { behaviours.values().forEach(tb -> {
if (!tb.isPaused()) if (!tb.isPaused())

View file

@ -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();

View file

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

View file

@ -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")));

View file

@ -61,6 +61,8 @@ public class ScrollValueRenderer {
} else } else
render(world, pos, face, behaviour, highlight); render(world, pos, face, behaviour, highlight);
TessellatorHelper.cleanUpAfterDrawing(); TessellatorHelper.cleanUpAfterDrawing();
GlStateManager.enableAlphaTest();
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.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,

View file

@ -23,7 +23,6 @@ public class TessellatorHelper {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.pushLightingAttributes(); GlStateManager.pushLightingAttributes();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.enableAlphaTest();
GlStateManager.color4f(1, 1, 1, 1); GlStateManager.color4f(1, 1, 1, 1);
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo(); ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
@ -45,7 +44,7 @@ public class TessellatorHelper {
GlStateManager.color3f(1, 1, 1); GlStateManager.color3f(1, 1, 1);
} }
public static void fightZFighting(int id) { public static void fightZFighting(int id) {
long randomBits = (long) id * 493286711L; long randomBits = (long) id * 493286711L;
randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L; randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
@ -68,10 +67,10 @@ public class TessellatorHelper {
} }
public static void cleanUpAfterDrawing() { public static void cleanUpAfterDrawing() {
GlStateManager.disableAlphaTest();
GlStateManager.disableBlend();
GlStateManager.popAttributes(); GlStateManager.popAttributes();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.disableAlphaTest();
GlStateManager.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) {

View file

@ -0,0 +1,55 @@
package com.simibubi.create.foundation.utility.outliner;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class AABBOutline extends Outline {
private AxisAlignedBB bb = new AxisAlignedBB(new BlockPos(25, 70, 90)).expand(0, 1, 0);
@Override
public void render(BufferBuilder buffer) {
begin();
Vec3d color = ColorHelper.getRGB(0xFFFFFF);
float alpha = 1f;
AllSpecialTextures.BLANK.bind();
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);
Vec3d start = xyz;
renderAACuboidLine(start, Xyz, color, alpha, buffer);
renderAACuboidLine(start, xYz, color, alpha, buffer);
renderAACuboidLine(start, xyZ, color, alpha, buffer);
start = XyZ;
renderAACuboidLine(start, xyZ, color, alpha, buffer);
renderAACuboidLine(start, XYZ, color, alpha, buffer);
renderAACuboidLine(start, Xyz, color, alpha, buffer);
start = XYz;
renderAACuboidLine(start, xYz, color, alpha, buffer);
renderAACuboidLine(start, Xyz, color, alpha, buffer);
renderAACuboidLine(start, XYZ, color, alpha, buffer);
start = xYZ;
renderAACuboidLine(start, XYZ, color, alpha, buffer);
renderAACuboidLine(start, xyZ, color, alpha, buffer);
renderAACuboidLine(start, xYz, color, alpha, buffer);
draw();
}
}

View file

@ -0,0 +1,143 @@
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) {
begin();
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);
}
flush();
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);
}
draw();
}
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();
}
}
}

View file

@ -0,0 +1,109 @@
package com.simibubi.create.foundation.utility.outliner;
import org.lwjgl.opengl.GL11;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
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);
protected void begin() {
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP);
}
protected void draw() {
Tessellator.getInstance().draw();
}
protected void flush() {
draw();
begin();
}
protected void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, BufferBuilder buffer) {
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, buffer);
putQuad(a1, a2, a3, a4, rgb, alpha, buffer);
putQuad(a1, b1, b2, a2, rgb, alpha, buffer);
putQuad(a2, b2, b3, a3, rgb, alpha, buffer);
putQuad(a3, b3, b4, a4, rgb, alpha, buffer);
putQuad(a4, b4, b1, a1, rgb, alpha, buffer);
}
protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset,
BufferBuilder buffer) {
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, buffer);
}
protected void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, BufferBuilder buffer) {
putVertex(v1, rgb, 0, 0, alpha, buffer);
putVertex(v2, rgb, 1, 0, alpha, buffer);
putVertex(v3, rgb, 1, 1, alpha, buffer);
putVertex(v4, rgb, 0, 1, alpha, buffer);
}
protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, BufferBuilder buffer) {
int i = 15 << 20 | 15 << 4;
int j = i >> 16 & '\uffff';
int k = i & '\uffff';
buffer.pos(pos.x, pos.y, pos.z).tex(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha)
.lightmap(j, k).endVertex();
}
}

View file

@ -0,0 +1,58 @@
package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.platform.GlStateManager;
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.client.renderer.BufferBuilder;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class OutlineParticle extends Particle {
private Outline outline;
private OutlineParticle(Outline outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) {
super(worldIn, xCoordIn, yCoordIn, zCoordIn);
this.outline = outline;
this.maxAge = 1024;
}
public static OutlineParticle create(Outline outline) {
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
OutlineParticle effect = new OutlineParticle(outline, mc.world, player.posX, player.posY, player.posZ);
mc.particles.addEffect(effect);
return effect;
}
public void remove() {
isExpired = true;
}
@Override
public void renderParticle(BufferBuilder buffer, ActiveRenderInfo entityIn, float partialTicks, float rotationX,
float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) {
GlStateManager.pushMatrix();
Vec3d view = entityIn.getProjectedView();
GlStateManager.translated(-view.x, -view.y, -view.z);
GlStateManager.depthMask(false);
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
GlStateManager.enableBlend();
outline.render(buffer);
GlStateManager.disableBlend();
GlStateManager.depthMask(true);
GlStateManager.popMatrix();
}
@Override
public IParticleRenderType getRenderType() {
return IParticleRenderType.CUSTOM;
}
}

View file

@ -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;
@ -47,7 +46,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) {
@ -64,8 +66,6 @@ public abstract class KineticBlock extends Block implements IRotate {
return null; return null;
} }
// Block
@Override @Override
public boolean hasTileEntity(BlockState state) { public boolean hasTileEntity(BlockState state) {
return true; return true;
@ -79,8 +79,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())
@ -90,8 +90,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 @Override

View file

@ -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));
@ -188,7 +197,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
networkTag.putFloat("Stress", stress); networkTag.putFloat("Stress", stress);
networkTag.putFloat("Capacity", capacity); networkTag.putFloat("Capacity", capacity);
networkTag.putInt("Size", networkSize); networkTag.putInt("Size", networkSize);
if (lastStressApplied != 0) if (lastStressApplied != 0)
networkTag.putFloat("AddedStress", lastStressApplied); networkTag.putFloat("AddedStress", lastStressApplied);
if (lastCapacityProvided != 0) if (lastCapacityProvided != 0)
@ -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;
} }

View file

@ -12,6 +12,8 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M
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.PulleyTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
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.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;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
@ -82,7 +84,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 +128,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;
} }
@ -187,6 +193,8 @@ public class BlockMovementTraits {
return state.get(PortableStorageInterfaceBlock.FACING) == facing; return state.get(PortableStorageInterfaceBlock.FACING) == facing;
if (AllBlocks.HARVESTER.typeOf(state)) if (AllBlocks.HARVESTER.typeOf(state))
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);
} }

View file

@ -13,10 +13,11 @@ import com.mojang.blaze3d.platform.GlStateManager;
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.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.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;
@ -30,13 +31,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 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;
} }
@ -80,14 +83,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;
} }
@ -113,8 +121,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;
} }
@ -162,13 +173,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();
} }
} }
@ -190,17 +207,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;
GlStateManager.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) {

View file

@ -26,13 +26,16 @@ 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.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.PulleyTileEntity;
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.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;
@ -53,6 +56,7 @@ import net.minecraft.util.BlockRenderLayer;
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;
@ -117,7 +121,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--) {
@ -147,6 +152,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))
@ -154,6 +161,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)) {
@ -164,7 +172,27 @@ public abstract class Contraption {
if (prevPos != null && !visited.contains(prevPos)) if (prevPos != null && !visited.contains(prevPos))
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);
@ -188,7 +216,7 @@ public abstract class Contraption {
if (limit <= -1) if (limit <= -1)
return false; return false;
} }
BlockPos searchPos = pos; BlockPos searchPos = pos;
while (limit-- >= 0) { while (limit-- >= 0) {
searchPos = searchPos.offset(direction.getOpposite()); searchPos = searchPos.offset(direction.getOpposite());
@ -202,17 +230,19 @@ public abstract class Contraption {
} }
break; break;
} }
if (limit <= -1) if (limit <= -1)
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);
} }
// 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);
@ -224,14 +254,15 @@ public abstract class Contraption {
return false; return false;
continue; continue;
} }
if (!visited.contains(offsetPos) if (!visited.contains(offsetPos) && ((isSlimeBlock && !BlockMovementTraits.isBrittle(blockState))
&& (isSlimeBlock || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()))) || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite())))
frontier.add(offsetPos); frontier.add(offsetPos);
} }
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;
} }
@ -497,8 +528,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,22 +545,13 @@ 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())

View file

@ -432,7 +432,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
} }
remove(); remove();
} }
@Override @Override
protected void doWaterSplashEffect() { protected void doWaterSplashEffect() {
} }

View file

@ -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);
@ -62,7 +67,7 @@ public class BearingContraption extends Contraption {
public int getSailBlocks() { public int getSailBlocks() {
return sailBlocks; return sailBlocks;
} }
public Direction getFacing() { public Direction getFacing() {
return facing; return facing;
} }

View file

@ -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;
@ -205,7 +208,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
public void attach(ContraptionEntity contraption) { public void attach(ContraptionEntity contraption) {
if (!(contraption.getContraption() instanceof ClockworkContraption)) if (!(contraption.getContraption() instanceof ClockworkContraption))
return; return;
ClockworkContraption cc = (ClockworkContraption) contraption.getContraption(); ClockworkContraption cc = (ClockworkContraption) contraption.getContraption();
markDirty(); markDirty();
Direction facing = getBlockState().get(BlockStateProperties.FACING); Direction facing = getBlockState().get(BlockStateProperties.FACING);
@ -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
@ -302,5 +307,5 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
public boolean isRunning() { public boolean isRunning() {
return running; return running;
} }
} }

View file

@ -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())

View file

@ -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());
@ -172,7 +176,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
sendData(); sendData();
updateGeneratedRotation(); updateGeneratedRotation();
} }
@Override @Override
public void updateGeneratedRotation() { public void updateGeneratedRotation() {
super.updateGeneratedRotation(); super.updateGeneratedRotation();
@ -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
@ -298,7 +304,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
public boolean isAttachedTo(ContraptionEntity contraption) { public boolean isAttachedTo(ContraptionEntity contraption) {
return movedContraption == contraption; return movedContraption == contraption;
} }
public boolean isRunning() { public boolean isRunning() {
return running; return running;
} }

View file

@ -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))

View file

@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
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 net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -61,8 +62,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;
} }

View file

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

View file

@ -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();

View file

@ -13,6 +13,7 @@ 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;
@ -63,17 +64,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 +130,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 +151,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 +161,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
@ -165,7 +180,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 +193,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;

View file

@ -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.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
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;
@ -9,6 +8,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;
@ -41,6 +41,18 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
return true; return true;
} }
@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);
}
}
@Override @Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
@ -76,27 +88,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);
} }

View file

@ -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();

View file

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

View file

@ -87,14 +87,15 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen
return false; return false;
} }
if (player instanceof ClientPlayerEntity) DistExecutor.runWhenOn(Dist.CLIENT,
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> withTileEntityDo(worldIn, pos, this::displayScreen)); () -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player)));
return true; return true;
} }
@OnlyIn(value = Dist.CLIENT) @OnlyIn(value = Dist.CLIENT)
protected void displayScreen(SequencedGearshiftTileEntity te) { protected void displayScreen(SequencedGearshiftTileEntity te, PlayerEntity player) {
ScreenOpener.open(new SequencedGearshiftScreen(te)); if (player instanceof ClientPlayerEntity)
ScreenOpener.open(new SequencedGearshiftScreen(te));
} }
@Override @Override

View file

@ -418,9 +418,9 @@ public class BeltBlock extends HorizontalKineticBlock
// Init belts // Init belts
int index = 0; int index = 0;
List<BlockPos> beltChain = getBeltChain(world, pos); List<BlockPos> beltChain = getBeltChain(world, currentPos);
if (beltChain.size() < 2) { if (beltChain.size() < 2) {
world.destroyBlock(pos, true); world.destroyBlock(currentPos, true);
return; return;
} }
@ -428,7 +428,7 @@ public class BeltBlock extends HorizontalKineticBlock
TileEntity tileEntity = world.getTileEntity(beltPos); TileEntity tileEntity = world.getTileEntity(beltPos);
if (tileEntity instanceof BeltTileEntity) { if (tileEntity instanceof BeltTileEntity) {
BeltTileEntity te = (BeltTileEntity) tileEntity; BeltTileEntity te = (BeltTileEntity) tileEntity;
te.setController(pos); te.setController(currentPos);
te.beltLength = beltChain.size(); te.beltLength = beltChain.size();
te.index = index; te.index = index;
te.attachKinetics(); te.attachKinetics();
@ -446,7 +446,7 @@ public class BeltBlock extends HorizontalKineticBlock
if (te.isController() && isVertical) if (te.isController() && isVertical)
te.getInventory().ejectAll(); te.getInventory().ejectAll();
} else { } else {
world.destroyBlock(pos, true); world.destroyBlock(currentPos, true);
return; return;
} }
index++; index++;

View file

@ -66,11 +66,6 @@ public class BeltTileEntity extends KineticTileEntity {
color = -1; color = -1;
} }
@Override
public void initialize() {
super.initialize();
}
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
@ -164,7 +159,9 @@ public class BeltTileEntity extends KineticTileEntity {
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
attachmentTracker.write(compound); attachmentTracker.write(compound);
compound.put("Controller", NBTUtil.writeBlockPos(controller));
if (controller != null)
compound.put("Controller", NBTUtil.writeBlockPos(controller));
compound.putBoolean("IsController", isController()); compound.putBoolean("IsController", isController());
compound.putInt("Color", color); compound.putInt("Color", color);
compound.putInt("Length", beltLength); compound.putInt("Length", beltLength);
@ -178,21 +175,32 @@ public class BeltTileEntity extends KineticTileEntity {
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
super.read(compound); super.read(compound);
if (compound.getBoolean("IsController")) if (compound.getBoolean("IsController"))
controller = pos; controller = pos;
else
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
if (!compound.contains("DontClearAttachments")) if (!wasMoved) {
if (!isController())
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
trackerUpdateTag = compound; trackerUpdateTag = compound;
color = compound.getInt("Color"); color = compound.getInt("Color");
beltLength = compound.getInt("Length"); beltLength = compound.getInt("Length");
index = compound.getInt("Index"); index = compound.getInt("Index");
}
if (isController()) if (isController())
getInventory().read(compound.getCompound("Inventory")); getInventory().read(compound.getCompound("Inventory"));
} }
@Override
public void clearKineticInformation() {
super.clearKineticInformation();
beltLength = 0;
index = 0;
controller = null;
trackerUpdateTag = new CompoundNBT();
}
public void applyColor(DyeColor colorIn) { public void applyColor(DyeColor colorIn) {
int colorValue = colorIn.getMapColor().colorValue; int colorValue = colorIn.getMapColor().colorValue;
for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) { for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) {
@ -206,6 +214,8 @@ public class BeltTileEntity extends KineticTileEntity {
} }
public BeltTileEntity getControllerTE() { public BeltTileEntity getControllerTE() {
if (controller == null)
return null;
if (!world.isBlockPresent(controller)) if (!world.isBlockPresent(controller))
return null; return null;
TileEntity te = world.getTileEntity(controller); TileEntity te = world.getTileEntity(controller);
@ -219,11 +229,11 @@ public class BeltTileEntity extends KineticTileEntity {
} }
public BlockPos getController() { public BlockPos getController() {
return controller; return controller == null ? pos : controller;
} }
public boolean isController() { public boolean isController() {
return controller.equals(pos); return pos.equals(controller);
} }
public float getBeltMovementSpeed() { public float getBeltMovementSpeed() {

View file

@ -1,8 +1,5 @@
package com.simibubi.create.modules.contraptions.relays.encased; package com.simibubi.create.modules.contraptions.relays.encased;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@ -26,13 +23,7 @@ public class ClutchBlock extends GearshiftBlock {
boolean previouslyPowered = state.get(POWERED); boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != worldIn.isBlockPowered(pos)) { if (previouslyPowered != worldIn.isBlockPowered(pos)) {
worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16); worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16);
TileEntity te = worldIn.getTileEntity(pos); detachKinetics(worldIn, pos, previouslyPowered);
if (te == null || !(te instanceof KineticTileEntity))
return;
if (previouslyPowered)
RotationPropagator.handleAdded(worldIn, pos, (KineticTileEntity) te);
else
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) te);
} }
} }

View file

@ -1,7 +1,10 @@
package com.simibubi.create.modules.contraptions.relays.encased; package com.simibubi.create.modules.contraptions.relays.encased;
import java.util.Random;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.modules.contraptions.RotationPropagator; import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEntity; import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -15,6 +18,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.TickPriority;
import net.minecraft.world.World; import net.minecraft.world.World;
public class GearshiftBlock extends EncasedShaftBlock implements ITE<GearshiftTileEntity> { public class GearshiftBlock extends EncasedShaftBlock implements ITE<GearshiftTileEntity> {
@ -51,7 +55,7 @@ public class GearshiftBlock extends EncasedShaftBlock implements ITE<GearshiftTi
boolean previouslyPowered = state.get(POWERED); boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != worldIn.isBlockPowered(pos)) { if (previouslyPowered != worldIn.isBlockPowered(pos)) {
withTileEntityDo(worldIn, pos, te -> RotationPropagator.handleRemoved(worldIn, pos, te)); detachKinetics(worldIn, pos, true);
worldIn.setBlockState(pos, state.cycle(POWERED), 2); worldIn.setBlockState(pos, state.cycle(POWERED), 2);
} }
} }
@ -65,4 +69,24 @@ public class GearshiftBlock extends EncasedShaftBlock implements ITE<GearshiftTi
return GearshiftTileEntity.class; return GearshiftTileEntity.class;
} }
public void detachKinetics(World worldIn, BlockPos pos, boolean reAttachNextTick) {
TileEntity te = worldIn.getTileEntity(pos);
if (te == null || !(te instanceof KineticTileEntity))
return;
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) te);
// Re-attach next tick
if (reAttachNextTick)
worldIn.getPendingBlockTicks().scheduleTick(pos, this, 0, TickPriority.EXTREMELY_HIGH);
}
@Override
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
TileEntity te = worldIn.getTileEntity(pos);
if (te == null || !(te instanceof KineticTileEntity))
return;
KineticTileEntity kte = (KineticTileEntity) te;
RotationPropagator.handleAdded(worldIn, pos, kte);
}
} }

View file

@ -78,8 +78,6 @@ public class SymmetryHandler {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player; ClientPlayerEntity player = mc.player;
GL11.glEnable(GL11.GL_BLEND);
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) { for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
ItemStack stackInSlot = player.inventory.getStackInSlot(i); ItemStack stackInSlot = player.inventory.getStackInSlot(i);
if (stackInSlot != null && AllItems.SYMMETRY_WAND.typeOf(stackInSlot) if (stackInSlot != null && AllItems.SYMMETRY_WAND.typeOf(stackInSlot)
@ -97,6 +95,7 @@ public class SymmetryHandler {
BufferBuilder buffer = Tessellator.getInstance().getBuffer(); BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
GlStateManager.enableBlend();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translated(0, yShift + .2f, 0); GlStateManager.translated(0, yShift + .2f, 0);
mc.getBlockRendererDispatcher().renderBlock(mirror.getModel(), pos, player.world, buffer, mc.getBlockRendererDispatcher().renderBlock(mirror.getModel(), pos, player.world, buffer,
@ -107,8 +106,6 @@ public class SymmetryHandler {
} }
} }
GL11.glDisable(GL11.GL_BLEND);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)

View file

@ -76,9 +76,11 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
transmitter = compound.getBoolean("Transmitter"); transmitter = compound.getBoolean("Transmitter");
receivedSignal = compound.getBoolean("Receive");
transmittedSignal = compound.getBoolean("Transmit");
super.read(compound); super.read(compound);
receivedSignal = compound.getBoolean("Receive");
if (world == null || world.isRemote || !link.newPosition)
transmittedSignal = compound.getBoolean("Transmit");
} }
@Override @Override

View file

@ -88,14 +88,15 @@ public class StockswitchBlock extends HorizontalBlock implements ITE<Stockswitch
@Override @Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
if (player instanceof ClientPlayerEntity) DistExecutor.runWhenOn(Dist.CLIENT,
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> withTileEntityDo(worldIn, pos, this::displayScreen)); () -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player)));
return true; return true;
} }
@OnlyIn(value = Dist.CLIENT) @OnlyIn(value = Dist.CLIENT)
protected void displayScreen(StockswitchTileEntity te) { protected void displayScreen(StockswitchTileEntity te, PlayerEntity player) {
ScreenOpener.open(new StockswitchScreen(te)); if (player instanceof ClientPlayerEntity)
ScreenOpener.open(new StockswitchScreen(te));
} }
@Override @Override

View file

@ -107,6 +107,10 @@ public class FlexcrateScreen extends AbstractSimiContainerScreen<FlexcrateContai
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (!AllBlocks.FLEXCRATE.typeOf(minecraft.world.getBlockState(te.getPos())))
minecraft.displayGuiScreen(null);
if (lastModification >= 0) if (lastModification >= 0)
lastModification++; lastModification++;
@ -114,7 +118,7 @@ public class FlexcrateScreen extends AbstractSimiContainerScreen<FlexcrateContai
lastModification = -1; lastModification = -1;
AllPackets.channel.sendToServer(new ConfigureFlexcratePacket(te.getPos(), allowedItems.getState())); AllPackets.channel.sendToServer(new ConfigureFlexcratePacket(te.getPos(), allowedItems.getState()));
} }
if (container.doubleCrate != te.isDoubleCrate()) if (container.doubleCrate != te.isDoubleCrate())
container.playerInventory.player.closeScreen(); container.playerInventory.player.closeScreen();
} }

View file

@ -4,7 +4,7 @@ loaderVersion="[28,)"
[[mods]] [[mods]]
modId="create" modId="create"
version="mc1.14-0.2.2b" version="mc1.14-0.2.3"
displayName="Create" displayName="Create"
#updateJSONURL="" #updateJSONURL=""
authors="simibubi" authors="simibubi"

View file

@ -151,12 +151,12 @@
"create.recipe.crushing":"Mahlen", "create.recipe.crushing":"Mahlen",
"create.recipe.splashing":"Waschen", "create.recipe.splashing":"Waschen",
"create.recipe.splashing.fan":"Propeller hinter fließendem Wasser", "create.recipe.splashing.fan":"Propeller hinter fließendem Wasser",
"create.recipe.smokingViaFan":"Räuchern", "create.recipe.smoking_via_fan":"Räuchern",
"create.recipe.smokingViaFan.fan":"Propeller hinter Feuer", "create.recipe.smoking_via_fan.fan":"Propeller hinter Feuer",
"create.recipe.blastingViaFan":"Schmelzen", "create.recipe.blasting_via_fan":"Schmelzen",
"create.recipe.blastingViaFan.fan":"Propeller hinter Lava", "create.recipe.blasting_via_fan.fan":"Propeller hinter Lava",
"create.recipe.pressing":"Mechanische Presse", "create.recipe.pressing":"Mechanische Presse",
"create.recipe.blockzapperUpgrade":"Blockpistole", "create.recipe.blockzapper_upgrade":"Blockpistole",
"create.recipe.processing.chance":"Chance: %1$s%%", "create.recipe.processing.chance":"Chance: %1$s%%",
"create.generic.range":"Reichweite", "create.generic.range":"Reichweite",

View file

@ -36,6 +36,8 @@
"item.create.crushed_gold": "Crushed Gold Ore", "item.create.crushed_gold": "Crushed Gold Ore",
"item.create.sand_paper": "Sand Paper", "item.create.sand_paper": "Sand Paper",
"item.create.red_sand_paper": "Red Sand Paper", "item.create.red_sand_paper": "Red Sand Paper",
"item.create.super_glue": "Super Glue",
"item.create.antioxidant": "Antioxidant Spray",
"item.create.brass_ingot": "Brass Ingot", "item.create.brass_ingot": "Brass Ingot",
"item.create.brass_sheet": "Brass Sheets", "item.create.brass_sheet": "Brass Sheets",
@ -272,17 +274,17 @@
"create.recipe.milling": "Milling", "create.recipe.milling": "Milling",
"create.recipe.splashing": "Bulk Washing", "create.recipe.splashing": "Bulk Washing",
"create.recipe.splashing.fan": "Fan behind Flowing Water", "create.recipe.splashing.fan": "Fan behind Flowing Water",
"create.recipe.smokingViaFan": "Bulk Smoking", "create.recipe.smoking_via_fan": "Bulk Smoking",
"create.recipe.smokingViaFan.fan": "Fan behind Fire", "create.recipe.smoking_via_fan.fan": "Fan behind Fire",
"create.recipe.blastingViaFan": "Bulk Smelting", "create.recipe.blasting_via_fan": "Bulk Smelting",
"create.recipe.blastingViaFan.fan": "Fan behind Lava", "create.recipe.blasting_via_fan.fan": "Fan behind Lava",
"create.recipe.pressing": "Pressing", "create.recipe.pressing": "Pressing",
"create.recipe.mixing": "Mixing", "create.recipe.mixing": "Mixing",
"create.recipe.packing": "Compacting", "create.recipe.packing": "Compacting",
"create.recipe.sawing": "Sawing", "create.recipe.sawing": "Sawing",
"create.recipe.mechanical_crafting": "Mechanical Crafting", "create.recipe.mechanical_crafting": "Mechanical Crafting",
"create.recipe.block_cutting": "Block Cutting", "create.recipe.block_cutting": "Block Cutting",
"create.recipe.blockzapperUpgrade": "Handheld Blockzapper", "create.recipe.blockzapper_upgrade": "Handheld Blockzapper",
"create.recipe.sandpaper_polishing": "Sandpaper Polishing", "create.recipe.sandpaper_polishing": "Sandpaper Polishing",
"create.recipe.mystery_conversion": "Chromatic Metamorphosis", "create.recipe.mystery_conversion": "Chromatic Metamorphosis",
"create.recipe.processing.catalyst": "Catalyst", "create.recipe.processing.catalyst": "Catalyst",

View file

@ -283,17 +283,17 @@
"create.recipe.crushing": "Ecrasement", "create.recipe.crushing": "Ecrasement",
"create.recipe.splashing": "Lavage en vrac", "create.recipe.splashing": "Lavage en vrac",
"create.recipe.splashing.fan": "Ventilateur derrière de l'eau qui coule", "create.recipe.splashing.fan": "Ventilateur derrière de l'eau qui coule",
"create.recipe.smokingViaFan": "Fumer en vrac", "create.recipe.smoking_via_fan": "Fumer en vrac",
"create.recipe.smokingViaFan.fan": "Fan behind Fire", "create.recipe.smoking_via_fan.fan": "Fan behind Fire",
"create.recipe.blastingViaFan": "Ventilateur derrière du feu", "create.recipe.blasting_via_fan": "Ventilateur derrière du feu",
"create.recipe.blastingViaFan.fan": "Ventilateur derrière de la lave", "create.recipe.blasting_via_fan.fan": "Ventilateur derrière de la lave",
"create.recipe.pressing": "Pressage", "create.recipe.pressing": "Pressage",
"create.recipe.mixing": "Mixage", "create.recipe.mixing": "Mixage",
"create.recipe.packing": "Compactage", "create.recipe.packing": "Compactage",
"create.recipe.sawing": "Sciage", "create.recipe.sawing": "Sciage",
"create.recipe.mechanical_crafting": "Fabrication mécanique", "create.recipe.mechanical_crafting": "Fabrication mécanique",
"create.recipe.block_cutting": "Coupe de bloc", "create.recipe.block_cutting": "Coupe de bloc",
"create.recipe.blockzapperUpgrade": "Blockzappeur portable", "create.recipe.blockzapper_upgrade": "Blockzappeur portable",
"create.recipe.sandpaper_polishing": "Polissage au papier de verre", "create.recipe.sandpaper_polishing": "Polissage au papier de verre",
"create.recipe.mystery_conversion": "Métamorphose chromatique", "create.recipe.mystery_conversion": "Métamorphose chromatique",
"create.recipe.processing.catalyst": "Catalyseur", "create.recipe.processing.catalyst": "Catalyseur",

View file

@ -272,17 +272,17 @@
"create.recipe.milling": "製粉", "create.recipe.milling": "製粉",
"create.recipe.splashing": "一括洗浄", "create.recipe.splashing": "一括洗浄",
"create.recipe.splashing.fan": "流れる水の後ろにファンを置く", "create.recipe.splashing.fan": "流れる水の後ろにファンを置く",
"create.recipe.smokingViaFan": "一括燻製", "create.recipe.smoking_via_fan": "一括燻製",
"create.recipe.smokingViaFan.fan": "炎の後ろにファンを置く", "create.recipe.smoking_via_fan.fan": "炎の後ろにファンを置く",
"create.recipe.blastingViaFan": "一括製錬", "create.recipe.blasting_via_fan": "一括製錬",
"create.recipe.blastingViaFan.fan": "溶岩の後ろにファンを置く", "create.recipe.blasting_via_fan.fan": "溶岩の後ろにファンを置く",
"create.recipe.pressing": "押しつぶし", "create.recipe.pressing": "押しつぶし",
"create.recipe.mixing": "混合", "create.recipe.mixing": "混合",
"create.recipe.packing": "圧縮", "create.recipe.packing": "圧縮",
"create.recipe.sawing": "製材", "create.recipe.sawing": "製材",
"create.recipe.mechanical_crafting": "メカニカルクラフト", "create.recipe.mechanical_crafting": "メカニカルクラフト",
"create.recipe.block_cutting": "ブロックカット", "create.recipe.block_cutting": "ブロックカット",
"create.recipe.blockzapperUpgrade": "携帯型ブロックザッパー", "create.recipe.blockzapper_upgrade": "携帯型ブロックザッパー",
"create.recipe.sandpaper_polishing": "紙やすりでの研磨", "create.recipe.sandpaper_polishing": "紙やすりでの研磨",
"create.recipe.mystery_conversion": "色彩変態", "create.recipe.mystery_conversion": "色彩変態",
"create.recipe.processing.catalyst": "触媒", "create.recipe.processing.catalyst": "触媒",

View file

@ -191,16 +191,16 @@
"create.recipe.crushing": "Verpulveren", "create.recipe.crushing": "Verpulveren",
"create.recipe.splashing": "Bulk Wassen", "create.recipe.splashing": "Bulk Wassen",
"create.recipe.splashing.fan": "Ventilator achter vloeiend water", "create.recipe.splashing.fan": "Ventilator achter vloeiend water",
"create.recipe.smokingViaFan": "Bulk Rook", "create.recipe.smoking_via_fan": "Bulk Rook",
"create.recipe.smokingViaFan.fan": "Ventilator achter vuur", "create.recipe.smoking_via_fan.fan": "Ventilator achter vuur",
"create.recipe.blastingViaFan": "Bulk Smelten", "create.recipe.blasting_via_fan": "Bulk Smelten",
"create.recipe.blastingViaFan.fan": "\"Ventilator achter Lava", "create.recipe.blasting_via_fan.fan": "\"Ventilator achter Lava",
"create.recipe.pressing": "Persen", "create.recipe.pressing": "Persen",
"create.recipe.mixing": "Mengen", "create.recipe.mixing": "Mengen",
"create.recipe.packing": "Compressen", "create.recipe.packing": "Compressen",
"create.recipe.sawing": "Zagen", "create.recipe.sawing": "Zagen",
"create.recipe.block_cutting": "Blok Zagen", "create.recipe.block_cutting": "Blok Zagen",
"create.recipe.blockzapperUpgrade": "Blokzapper", "create.recipe.blockzapper_upgrade": "Blokzapper",
"create.recipe.processing.chance": "%1$s%% Kans", "create.recipe.processing.chance": "%1$s%% Kans",
"create.generic.range": "Omvang", "create.generic.range": "Omvang",

View file

@ -153,12 +153,12 @@
"create.recipe.crushing": "Moendo", "create.recipe.crushing": "Moendo",
"create.recipe.splashing": "Lavando em Massa", "create.recipe.splashing": "Lavando em Massa",
"create.recipe.splashing.fan": "Ventilador atras de Água corrente", "create.recipe.splashing.fan": "Ventilador atras de Água corrente",
"create.recipe.smokingViaFan": "Fumaceando em Massa", "create.recipe.smoking_via_fan": "Fumaceando em Massa",
"create.recipe.smokingViaFan.fan": "Ventilador atras de Fogo", "create.recipe.smoking_via_fan.fan": "Ventilador atras de Fogo",
"create.recipe.blastingViaFan": "Fundindo em Massa", "create.recipe.blasting_via_fan": "Fundindo em Massa",
"create.recipe.blastingViaFan.fan": "Ventilador atras de Lava", "create.recipe.blasting_via_fan.fan": "Ventilador atras de Lava",
"create.recipe.pressing": "Prensa Mecânica", "create.recipe.pressing": "Prensa Mecânica",
"create.recipe.blockzapperUpgrade": "Blockzapper Portátil", "create.recipe.blockzapper_upgrade": "Blockzapper Portátil",
"create.recipe.processing.chance": "%1$s%% de chance", "create.recipe.processing.chance": "%1$s%% de chance",
"create.generic.range": "Área", "create.generic.range": "Área",

View file

@ -153,12 +153,12 @@
"create.recipe.crushing": "Дробление", "create.recipe.crushing": "Дробление",
"create.recipe.splashing": "Промывка вентилятором", "create.recipe.splashing": "Промывка вентилятором",
"create.recipe.splashing.fan": "Вентилятор за проточной водой", "create.recipe.splashing.fan": "Вентилятор за проточной водой",
"create.recipe.smokingViaFan": "Копчение вентилятором", "create.recipe.smoking_via_fan": "Копчение вентилятором",
"create.recipe.smokingViaFan.fan": "Вентилятор за огнём", "create.recipe.smoking_via_fan.fan": "Вентилятор за огнём",
"create.recipe.blastingViaFan": "Плавление вентилятором", "create.recipe.blasting_via_fan": "Плавление вентилятором",
"create.recipe.blastingViaFan.fan": "Вентелятор за лавой", "create.recipe.blasting_via_fan.fan": "Вентелятор за лавой",
"create.recipe.pressing": "Механический пресс", "create.recipe.pressing": "Механический пресс",
"create.recipe.blockzapperUpgrade": "Портативный размещатель блоков", "create.recipe.blockzapper_upgrade": "Портативный размещатель блоков",
"create.recipe.processing.chance": "%1$s%% шанс выпадения", "create.recipe.processing.chance": "%1$s%% шанс выпадения",
"create.generic.range": "Зона", "create.generic.range": "Зона",

View file

@ -283,17 +283,17 @@
"create.recipe.crushing": "批量粉碎", "create.recipe.crushing": "批量粉碎",
"create.recipe.splashing": "批量洗涤", "create.recipe.splashing": "批量洗涤",
"create.recipe.splashing.fan": "在鼓风机前方倒水", "create.recipe.splashing.fan": "在鼓风机前方倒水",
"create.recipe.smokingViaFan": "批量烟熏", "create.recipe.smoking_via_fan": "批量烟熏",
"create.recipe.smokingViaFan.fan": "在鼓风机前方点火", "create.recipe.smoking_via_fan.fan": "在鼓风机前方点火",
"create.recipe.blastingViaFan": "批量冶炼", "create.recipe.blasting_via_fan": "批量冶炼",
"create.recipe.blastingViaFan.fan": "在鼓风机前方倒岩浆", "create.recipe.blasting_via_fan.fan": "在鼓风机前方倒岩浆",
"create.recipe.pressing": "金属压片", "create.recipe.pressing": "金属压片",
"create.recipe.mixing": "混合搅拌", "create.recipe.mixing": "混合搅拌",
"create.recipe.packing": "压块塑形", "create.recipe.packing": "压块塑形",
"create.recipe.sawing": "木材切割", "create.recipe.sawing": "木材切割",
"create.recipe.mechanical_crafting": "自动合成", "create.recipe.mechanical_crafting": "自动合成",
"create.recipe.block_cutting": "方块切割", "create.recipe.block_cutting": "方块切割",
"create.recipe.blockzapperUpgrade": "手持式方块放置器", "create.recipe.blockzapper_upgrade": "手持式方块放置器",
"create.recipe.sandpaper_polishing": "砂纸抛光", "create.recipe.sandpaper_polishing": "砂纸抛光",
"create.recipe.mystery_conversion": "化合物变异", "create.recipe.mystery_conversion": "化合物变异",
"create.recipe.processing.catalyst": "催化剂", "create.recipe.processing.catalyst": "催化剂",

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/antioxidant"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/super_glue"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 218 B

View file

@ -0,0 +1,20 @@
{
"type": "create:crushing",
"ingredients": [
{
"item": "minecraft:glowstone"
}
],
"results": [
{
"item": "minecraft:glowstone_dust",
"count": 3
},
{
"item": "minecraft:glowstone_dust",
"count": 1,
"chance": 0.5
}
],
"processingTime": 150
}

View file

@ -0,0 +1,20 @@
{
"type": "create:crushing",
"ingredients": [
{
"item": "minecraft:nether_wart_block"
}
],
"results": [
{
"item": "minecraft:nether_wart",
"count": 6
},
{
"item": "minecraft:nether_wart",
"count": 2,
"chance": 0.5
}
],
"processingTime": 150
}