Millstone cont'd

- Overstressed components now show a tooltip, unless disabled in config
- JEI compat for millstone recipes
- Crushing Wheels now require mechanical crafting in order to be assembled
- Millstones now drop contents when broken
- Players can manually collect millstone outputs via right-click
- Fixed millstone removing ingredients before looking up a recipe
- Gauges no longer require a block to sit on (QOL)
This commit is contained in:
simibubi 2020-03-27 17:52:05 +01:00
parent c3f781b762
commit ca86273f5f
33 changed files with 550 additions and 122 deletions

View file

@ -67,7 +67,7 @@ public enum AllBlockPartials {
ROPE_COIL("pulley/rope_coil"), ROPE_COIL("pulley/rope_coil"),
ROPE_HALF("pulley/rope_half"), ROPE_HALF("pulley/rope_half"),
ROPE_HALF_MAGNET("pulley/rope_half_magnet"), ROPE_HALF_MAGNET("pulley/rope_half_magnet"),
MILL_STONE_COG("millstone/inner"), MILLSTONE_COG("millstone/inner"),
; ;

View file

@ -15,6 +15,7 @@ import com.simibubi.create.compat.jei.category.BlockCuttingCategory.CondensedBlo
import com.simibubi.create.compat.jei.category.BlockzapperUpgradeCategory; import com.simibubi.create.compat.jei.category.BlockzapperUpgradeCategory;
import com.simibubi.create.compat.jei.category.CrushingCategory; import com.simibubi.create.compat.jei.category.CrushingCategory;
import com.simibubi.create.compat.jei.category.MechanicalCraftingCategory; import com.simibubi.create.compat.jei.category.MechanicalCraftingCategory;
import com.simibubi.create.compat.jei.category.MillingCategory;
import com.simibubi.create.compat.jei.category.MixingCategory; import com.simibubi.create.compat.jei.category.MixingCategory;
import com.simibubi.create.compat.jei.category.MysteriousItemConversionCategory; import com.simibubi.create.compat.jei.category.MysteriousItemConversionCategory;
import com.simibubi.create.compat.jei.category.PackingCategory; import com.simibubi.create.compat.jei.category.PackingCategory;
@ -55,6 +56,7 @@ import net.minecraft.util.text.TextFormatting;
public class CreateJEI implements IModPlugin { public class CreateJEI implements IModPlugin {
private static ResourceLocation ID = new ResourceLocation(Create.ID, "jei_plugin"); private static ResourceLocation ID = new ResourceLocation(Create.ID, "jei_plugin");
private MillingCategory millingCategory;
private CrushingCategory crushingCategory; private CrushingCategory crushingCategory;
private SplashingCategory splashingCategory; private SplashingCategory splashingCategory;
private SmokingViaFanCategory smokingCategory; private SmokingViaFanCategory smokingCategory;
@ -76,6 +78,7 @@ public class CreateJEI implements IModPlugin {
} }
public CreateJEI() { public CreateJEI() {
millingCategory = new MillingCategory();
crushingCategory = new CrushingCategory(); crushingCategory = new CrushingCategory();
splashingCategory = new SplashingCategory(); splashingCategory = new SplashingCategory();
pressingCategory = new PressingCategory(); pressingCategory = new PressingCategory();
@ -99,14 +102,15 @@ public class CreateJEI implements IModPlugin {
@Override @Override
public void registerCategories(IRecipeCategoryRegistration registration) { public void registerCategories(IRecipeCategoryRegistration registration) {
registration.addRecipeCategories(crushingCategory, splashingCategory, pressingCategory, smokingCategory, registration.addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory,
blastingCategory, blockzapperCategory, mixingCategory, sawingCategory, blockCuttingCategory, smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory,
packingCategory, polishingCategory, mysteryConversionCategory, smallMechanicalCraftingCategory, blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory,
largeMechanicalCraftingCategory); smallMechanicalCraftingCategory, largeMechanicalCraftingCategory);
} }
@Override @Override
public void registerRecipes(IRecipeRegistration registration) { public void registerRecipes(IRecipeRegistration registration) {
registration.addRecipes(findRecipes(AllRecipes.MILLING), millingCategory.getUid());
registration.addRecipes(findRecipes(AllRecipes.CRUSHING), crushingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipes.CRUSHING), crushingCategory.getUid());
registration.addRecipes(findRecipesByTypeExcluding(AllRecipes.MILLING.getType(), AllRecipes.CRUSHING.getType()), registration.addRecipes(findRecipesByTypeExcluding(AllRecipes.MILLING.getType(), AllRecipes.CRUSHING.getType()),
crushingCategory.getUid()); crushingCategory.getUid());
@ -135,12 +139,15 @@ public class CreateJEI implements IModPlugin {
registration.addRecipes(findRecipes( registration.addRecipes(findRecipes(
r -> (r instanceof MechanicalCraftingRecipe) && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)), r -> (r instanceof MechanicalCraftingRecipe) && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
smallMechanicalCraftingCategory.getUid()); smallMechanicalCraftingCategory.getUid());
registration.addRecipes(findRecipes(r -> r.getType() == IRecipeType.CRAFTING && (r instanceof ShapedRecipe)
&& !(r instanceof MechanicalCraftingRecipe) && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
smallMechanicalCraftingCategory.getUid());
registration.addRecipes( registration.addRecipes(
findRecipes(r -> r.getType() == IRecipeType.CRAFTING && (r instanceof ShapedRecipe) findRecipes(
&& !MechanicalCraftingCategory.isSmall((ShapedRecipe) r)), r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)
&& (r instanceof ShapedRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
smallMechanicalCraftingCategory.getUid());
registration.addRecipes(findRecipes(
r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)
&& (r instanceof ShapedRecipe) && !MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
largeMechanicalCraftingCategory.getUid()); largeMechanicalCraftingCategory.getUid());
} }
@ -156,6 +163,7 @@ public class CreateJEI implements IModPlugin {
ItemStack blastingFan = fan.copy().setDisplayName( ItemStack blastingFan = fan.copy().setDisplayName(
new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan"))); new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan")));
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MILLSTONE.get()), millingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), crushingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), crushingCategory.getUid());
registration.addRecipeCatalyst(splashingFan, splashingCategory.getUid()); registration.addRecipeCatalyst(splashingFan, splashingCategory.getUid());
registration.addRecipeCatalyst(smokingFan, smokingCategory.getUid()); registration.addRecipeCatalyst(smokingFan, smokingCategory.getUid());

View file

@ -33,7 +33,7 @@ public class CrushingCategory implements IRecipeCategory<AbstractCrushingRecipe>
public CrushingCategory() { public CrushingCategory() {
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.CRUSHING_WHEEL.get()),
() -> new ItemStack(AllItems.FLOUR.get())); () -> new ItemStack(AllItems.CRUSHED_GOLD.get()));
} }
@Override @Override

View file

@ -0,0 +1,111 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
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.foundation.utility.Lang;
import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe;
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
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> {
private static ResourceLocation ID = new ResourceLocation(Create.ID, "milling");
private AnimatedMillstone millstone = new AnimatedMillstone();
private IDrawable icon;
private IDrawable background = new EmptyBackground(177, 53);
public MillingCategory() {
icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MILLSTONE.get()),
() -> new ItemStack(AllItems.FLOUR.get()));
}
@Override
public IDrawable getBackground() {
return background;
}
@Override
public ResourceLocation getUid() {
return ID;
}
@Override
public Class<? extends AbstractCrushingRecipe> getRecipeClass() {
return AbstractCrushingRecipe.class;
}
@Override
public String getTitle() {
return Lang.translate("recipe.milling");
}
@Override
public IDrawable getIcon() {
return icon;
}
@Override
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getPossibleOutputs());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, AbstractCrushingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 14, 8);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
boolean single = results.size() == 1;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;
int yOffset = (outputIndex / 2) * -19;
itemStacks.init(outputIndex + 1, false, single ? 139 : 133 + xOffset, 27 + yOffset);
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
}
CreateJEI.addStochasticTooltip(itemStacks, results);
}
@Override
public void draw(AbstractCrushingRecipe recipe, double mouseX, double mouseY) {
int size = recipe.getPossibleOutputs().size();
ScreenResources.JEI_SLOT.draw(14, 8);
ScreenResources.JEI_SHADOW.draw(30, 40);
ScreenResources.JEI_ARROW.draw(85, 32);
ScreenResources.JEI_DOWN_ARROW.draw(43, 4);
if (size > 1) {
for (int i = 0; i < size; i++) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;
ScreenResources.JEI_SLOT.draw(133 + xOffset, 27 + yOffset);
}
} else {
ScreenResources.JEI_SLOT.draw(139, 27);
}
millstone.draw(57, 27);
}
}

View file

@ -0,0 +1,55 @@
package com.simibubi.create.compat.jei.category.animations;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.IBakedModel;
public class AnimatedMillstone extends AnimatedKinetics {
@Override
public int getWidth() {
return 50;
}
@Override
public int getHeight() {
return 50;
}
@Override
public void draw(int xOffset, int yOffset) {
GlStateManager.pushMatrix();
GlStateManager.enableDepthTest();
GlStateManager.translatef(xOffset, yOffset, 0);
GlStateManager.rotatef(-15.5f, 1, 0, 0);
GlStateManager.rotatef(22.5f, 0, 1, 0);
GlStateManager.translatef(-45, -5, 0);
GlStateManager.scaled(.45f, .45f, .45f);
GlStateManager.pushMatrix();
ScreenElementRenderer.renderModel(this::cogwheel);
GlStateManager.popMatrix();
GlStateManager.pushMatrix();
ScreenElementRenderer.renderBlock(this::body);
GlStateManager.popMatrix();
GlStateManager.popMatrix();
}
private IBakedModel cogwheel() {
float t = 25;
GlStateManager.translatef(t, -t, -t);
GlStateManager.rotated(getCurrentAngle() * 2, 0, 1, 0);
GlStateManager.translatef(-t, t, t);
return AllBlockPartials.MILLSTONE_COG.get();
}
private BlockState body() {
return AllBlocks.MILLSTONE.get().getDefaultState();
}
}

View file

@ -5,6 +5,8 @@ public class CClient extends ConfigBase {
public ConfigGroup client = group(0, "client", public ConfigGroup client = group(0, "client",
"Client-only settings - If you're looking for general settings, look inside your worlds serverconfig folder!"); "Client-only settings - If you're looking for general settings, look inside your worlds serverconfig folder!");
public ConfigBool tooltips = b(true, "enableTooltips", "Show item descriptions on Shift and controls on Ctrl."); public ConfigBool tooltips = b(true, "enableTooltips", "Show item descriptions on Shift and controls on Ctrl.");
public ConfigBool enableOverstressedTooltip =
b(true, "enableOverstressedTooltip", "Display a tooltip when looking at overstressed components.");
public ConfigBool explainRenderErrors = public ConfigBool explainRenderErrors =
b(false, "explainRenderErrors", "Log a stack-trace when rendering issues happen within a moving contraption."); b(false, "explainRenderErrors", "Log a stack-trace when rendering issues happen within a moving contraption.");
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity"); public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.contraptions.base; package com.simibubi.create.modules.contraptions.base;
import static net.minecraft.util.text.TextFormatting.GOLD;
import static net.minecraft.util.text.TextFormatting.GRAY; import static net.minecraft.util.text.TextFormatting.GRAY;
import java.util.List; import java.util.List;
@ -19,6 +20,7 @@ import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import com.simibubi.create.modules.contraptions.base.IRotate.StressImpact; import com.simibubi.create.modules.contraptions.base.IRotate.StressImpact;
import com.simibubi.create.modules.contraptions.goggle.IHaveGoggleInformation; import com.simibubi.create.modules.contraptions.goggle.IHaveGoggleInformation;
import com.simibubi.create.modules.contraptions.goggle.IHaveHoveringInformation;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
@ -33,7 +35,8 @@ import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity, IHaveGoggleInformation { public abstract class KineticTileEntity extends SmartTileEntity
implements ITickableTileEntity, IHaveGoggleInformation, IHaveHoveringInformation {
public @Nullable Long network; public @Nullable Long network;
public @Nullable BlockPos source; public @Nullable BlockPos source;
@ -353,28 +356,51 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
return true; return true;
} }
@Override
public boolean addToTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean notFastEnough = !isSpeedRequirementFulfilled() && getSpeed() != 0;
if (overStressed && AllConfigs.CLIENT.enableOverstressedTooltip.get()) {
tooltip.add(spacing + GOLD + Lang.translate("gui.stress_gauge.overstressed"));
String hint = Lang.translate("gui.contraptions.network_overstressed",
I18n.format(getBlockState().getBlock().getTranslationKey()));
List<String> cutString = TooltipHelper.cutString(spacing + hint, GRAY, TextFormatting.WHITE);
for (int i = 0; i < cutString.size(); i++)
tooltip.add((i == 0 ? "" : spacing) + cutString.get(i));
return true;
}
if (notFastEnough) {
tooltip.add(spacing + GOLD + Lang.translate("tooltip.speedRequirement"));
String hint = Lang.translate("gui.contraptions.not_fast_enough",
I18n.format(getBlockState().getBlock().getTranslationKey()));
List<String> cutString = TooltipHelper.cutString(spacing + hint, GRAY, TextFormatting.WHITE);
for (int i = 0; i < cutString.size(); i++)
tooltip.add((i == 0 ? "" : spacing) + cutString.get(i));
return true;
}
return false;
}
@Override @Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) { public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = false; boolean added = false;
float stressAtBase = getStressApplied(); float stressAtBase = getStressApplied();
boolean notFastEnough = !isSpeedRequirementFulfilled() && getSpeed() != 0;
if (notFastEnough) {
tooltip.addAll(TooltipHelper.cutString(spacing + Lang.translate("gui.contraptions.not_fast_enough", I18n.format(getBlockState().getBlock().getTranslationKey())), GRAY, TextFormatting.WHITE));
added = true;
}
if (getStressApplied() != 0 && StressImpact.isEnabled()) { if (getStressApplied() != 0 && StressImpact.isEnabled()) {
tooltip.add(spacing + Lang.translate("gui.goggles.kinetic_stats")); tooltip.add(spacing + Lang.translate("gui.goggles.kinetic_stats"));
tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.stressImpact")); tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.stressImpact"));
float stressTotal = stressAtBase * Math.abs(getSpeed()); float stressTotal = stressAtBase * Math.abs(getSpeed());
String stressString = spacing + "%s%s" + Lang.translate("generic.unit.stress") + " " + TextFormatting.DARK_GRAY + "%s"; String stressString =
spacing + "%s%s" + Lang.translate("generic.unit.stress") + " " + TextFormatting.DARK_GRAY + "%s";
tooltip.add(String.format(stressString, TextFormatting.AQUA, IHaveGoggleInformation.format(stressAtBase), Lang.translate("gui.goggles.base_value"))); tooltip.add(String.format(stressString, TextFormatting.AQUA, IHaveGoggleInformation.format(stressAtBase),
tooltip.add(String.format(stressString, TextFormatting.GRAY, IHaveGoggleInformation.format(stressTotal), Lang.translate("gui.goggles.at_current_speed"))); Lang.translate("gui.goggles.base_value")));
tooltip.add(String.format(stressString, TextFormatting.GRAY, IHaveGoggleInformation.format(stressTotal),
Lang.translate("gui.goggles.at_current_speed")));
added = true; added = true;
} }

View file

@ -27,7 +27,7 @@ public class MillingRecipe extends AbstractCrushingRecipe {
@Override @Override
protected int getMaxOutputCount() { protected int getMaxOutputCount() {
return 7; return 4;
} }
} }

View file

@ -5,14 +5,27 @@ import com.simibubi.create.modules.contraptions.base.KineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
public class MillstoneBlock extends KineticBlock { public class MillstoneBlock extends KineticBlock {
@ -40,6 +53,81 @@ public class MillstoneBlock extends KineticBlock {
return face == Direction.DOWN; return face == Direction.DOWN;
} }
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (!player.getHeldItem(handIn).isEmpty())
return false;
if (worldIn.getTileEntity(pos) == null)
return false;
if (worldIn.isRemote)
return true;
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (!(tileEntity instanceof MillstoneTileEntity))
return false;
MillstoneTileEntity millstone = (MillstoneTileEntity) tileEntity;
IItemHandlerModifiable inv = millstone.outputInv;
for (int slot = 0; slot < inv.getSlots(); slot++) {
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
inv.setStackInSlot(slot, ItemStack.EMPTY);
}
millstone.markDirty();
millstone.sendData();
return true;
}
@Override
public void onLanded(IBlockReader worldIn, Entity entityIn) {
super.onLanded(worldIn, entityIn);
if (entityIn.world.isRemote)
return;
if (!(entityIn instanceof ItemEntity))
return;
BlockPos pos = entityIn.getPosition();
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (!(tileEntity instanceof MillstoneTileEntity)) {
tileEntity = worldIn.getTileEntity(pos.down());
if (!(tileEntity instanceof MillstoneTileEntity))
return;
}
MillstoneTileEntity millstone = (MillstoneTileEntity) tileEntity;
ItemEntity itemEntity = (ItemEntity) entityIn;
LazyOptional<IItemHandler> capability = millstone.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
if (!capability.isPresent())
return;
ItemStack remainder = capability.orElse(new ItemStackHandler()).insertItem(0, itemEntity.getItem(), false);
if (remainder.isEmpty())
itemEntity.remove();
if (remainder.getCount() < itemEntity.getItem().getCount())
itemEntity.setItem(remainder);
}
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (!(tileEntity instanceof MillstoneTileEntity))
return;
MillstoneTileEntity te = (MillstoneTileEntity) tileEntity;
for (int slot = 0; slot < te.inputInv.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inputInv.getStackInSlot(slot));
}
for (int slot = 0; slot < te.outputInv.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.outputInv.getStackInSlot(slot));
}
worldIn.removeTileEntity(pos);
}
}
@Override @Override
public boolean hasIntegratedCogwheel(IWorldReader world, BlockPos pos, BlockState state) { public boolean hasIntegratedCogwheel(IWorldReader world, BlockPos pos, BlockState state) {
return true; return true;

View file

@ -10,7 +10,7 @@ public class MillstoneRenderer extends KineticTileEntityRenderer {
@Override @Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) { protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.bufferCache.renderPartial(AllBlockPartials.MILL_STONE_COG, te.getBlockState()); return CreateClient.bufferCache.renderPartial(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
} }
} }

View file

@ -65,7 +65,6 @@ public class MillstoneTileEntity extends KineticTileEntity {
if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) { if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) {
Optional<MillingRecipe> recipe = Optional<MillingRecipe> recipe =
world.getRecipeManager().getRecipe(AllRecipes.MILLING.getType(), inventoryIn, world); world.getRecipeManager().getRecipe(AllRecipes.MILLING.getType(), inventoryIn, world);
inputInv.getStackInSlot(0).shrink(1);
if (!recipe.isPresent()) { if (!recipe.isPresent()) {
timer = 100; timer = 100;
sendData(); sendData();
@ -83,9 +82,6 @@ public class MillstoneTileEntity extends KineticTileEntity {
private void process() { private void process() {
RecipeWrapper inventoryIn = new RecipeWrapper(inputInv); RecipeWrapper inventoryIn = new RecipeWrapper(inputInv);
ItemStack stackInSlot = inputInv.getStackInSlot(0);
stackInSlot.shrink(1);
inputInv.setStackInSlot(0, stackInSlot);
if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) { if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) {
Optional<MillingRecipe> recipe = Optional<MillingRecipe> recipe =
@ -95,6 +91,9 @@ public class MillstoneTileEntity extends KineticTileEntity {
lastRecipe = recipe.get(); lastRecipe = recipe.get();
} }
ItemStack stackInSlot = inputInv.getStackInSlot(0);
stackInSlot.shrink(1);
inputInv.setStackInSlot(0, stackInSlot);
lastRecipe.rollResults().forEach(stack -> ItemHandlerHelper.insertItemStacked(outputInv, stack, false)); lastRecipe.rollResults().forEach(stack -> ItemHandlerHelper.insertItemStacked(outputInv, stack, false));
sendData(); sendData();
markDirty(); markDirty();

View file

@ -41,17 +41,34 @@ public class GoggleOverlayRenderer {
ItemStack goggles = mc.player.getItemStackFromSlot(EquipmentSlotType.HEAD); ItemStack goggles = mc.player.getItemStackFromSlot(EquipmentSlotType.HEAD);
TileEntity te = world.getTileEntity(pos); TileEntity te = world.getTileEntity(pos);
if (!AllItems.GOGGLES.typeOf(goggles)) boolean goggleInformation = te instanceof IHaveGoggleInformation;
return; boolean hoveringInformation = te instanceof IHaveHoveringInformation;
if (!(te instanceof IHaveGoggleInformation)) if (!goggleInformation && !hoveringInformation)
return; return;
IHaveGoggleInformation gte = (IHaveGoggleInformation) te;
List<String> tooltip = new ArrayList<>(); List<String> tooltip = new ArrayList<>();
if (goggleInformation && AllItems.GOGGLES.typeOf(goggles)) {
IHaveGoggleInformation gte = (IHaveGoggleInformation) te;
if (!gte.addToGoggleTooltip(tooltip, mc.player.isSneaking())) if (!gte.addToGoggleTooltip(tooltip, mc.player.isSneaking()))
goggleInformation = false;
}
if (hoveringInformation) {
boolean goggleAddedInformation = !tooltip.isEmpty();
if (goggleAddedInformation)
tooltip.add("");
IHaveHoveringInformation hte = (IHaveHoveringInformation) te;
if (!hte.addToTooltip(tooltip, mc.player.isSneaking()))
hoveringInformation = false;
if (goggleAddedInformation && !hoveringInformation)
tooltip.remove(tooltip.size() - 1);
}
if (!goggleInformation && !hoveringInformation)
return;
if (tooltip.isEmpty())
return; return;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@ -70,7 +87,7 @@ public class GoggleOverlayRenderer {
tooltipScreen.init(mc, mc.mainWindow.getScaledWidth(), mc.mainWindow.getScaledHeight()); tooltipScreen.init(mc, mc.mainWindow.getScaledWidth(), mc.mainWindow.getScaledHeight());
tooltipScreen.renderTooltip(tooltip, tooltipScreen.width / 2, tooltipScreen.height / 2); tooltipScreen.renderTooltip(tooltip, tooltipScreen.width / 2, tooltipScreen.height / 2);
ItemStack item = goggles; ItemStack item = AllItems.GOGGLES.asStack();
ScreenElementRenderer.render3DItem(() -> { ScreenElementRenderer.render3DItem(() -> {
GlStateManager.translated(tooltipScreen.width / 2 + 10, tooltipScreen.height / 2 - 16, 0); GlStateManager.translated(tooltipScreen.width / 2 + 10, tooltipScreen.height / 2 - 16, 0);
return item; return item;

View file

@ -0,0 +1,14 @@
package com.simibubi.create.modules.contraptions.goggle;
import java.util.List;
/*
* Implement this Interface in the TileEntity class that wants to add info to the screen
* */
public interface IHaveHoveringInformation {
default boolean addToTooltip(List<String> tooltip, boolean isPlayerSneaking){
return false;
}
}

View file

@ -51,6 +51,8 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
} }
public void gatherInputs() { public void gatherInputs() {
if (!basinInv.isPresent())
return;
BasinInventory inv = (BasinInventory) basinInv.orElse(null); BasinInventory inv = (BasinInventory) basinInv.orElse(null);
inputs = new ArrayList<>(); inputs = new ArrayList<>();
IItemHandlerModifiable inputHandler = inv.getInputHandler(); IItemHandlerModifiable inputHandler = inv.getInputHandler();

View file

@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.base.IRotate;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -25,7 +26,6 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class GaugeBlock extends DirectionalAxisKineticBlock { public class GaugeBlock extends DirectionalAxisKineticBlock {
@ -65,34 +65,41 @@ public class GaugeBlock extends DirectionalAxisKineticBlock {
return Blocks.SPRUCE_PLANKS.getMaterialColor(state, worldIn, pos); return Blocks.SPRUCE_PLANKS.getMaterialColor(state, worldIn, pos);
} }
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
World world = context.getWorld();
Direction face = context.getFace();
BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite());
BlockState placedOnState = world.getBlockState(placedOnPos);
Block block = placedOnState.getBlock();
if (block instanceof IRotate && ((IRotate) block).hasShaftTowards(world, placedOnPos, placedOnState, face)) {
BlockState toPlace = getDefaultState();
Direction horizontalFacing = context.getPlacementHorizontalFacing();
Direction nearestLookingDirection = context.getNearestLookingDirection();
boolean lookPositive = nearestLookingDirection.getAxisDirection() == AxisDirection.POSITIVE;
if (face.getAxis() == Axis.X) {
toPlace = toPlace.with(FACING, lookPositive ? Direction.NORTH : Direction.SOUTH)
.with(AXIS_ALONG_FIRST_COORDINATE, true);
} else if (face.getAxis() == Axis.Y) {
toPlace = toPlace.with(FACING, horizontalFacing.getOpposite()).with(AXIS_ALONG_FIRST_COORDINATE,
horizontalFacing.getAxis() == Axis.X);
} else {
toPlace = toPlace.with(FACING, lookPositive ? Direction.WEST : Direction.EAST)
.with(AXIS_ALONG_FIRST_COORDINATE, false);
}
return toPlace;
}
return super.getStateForPlacement(context);
}
@Override @Override
protected boolean hasStaticPart() { protected boolean hasStaticPart() {
return true; return true;
} }
@Override
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
Direction facing = state.get(FACING).getOpposite();
BlockPos neighbourPos = pos.offset(facing);
BlockState neighbour = worldIn.getBlockState(neighbourPos);
return Block.hasSolidSide(neighbour, worldIn, neighbourPos, facing.getOpposite());
}
@Override
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
if (worldIn.isRemote)
return;
Direction blockFacing = state.get(FACING);
if (fromPos.equals(pos.offset(blockFacing.getOpposite()))) {
if (!isValidPosition(state, worldIn, pos)) {
worldIn.destroyBlock(pos, true);
return;
}
}
}
@Override @Override
protected Direction getFacingForPlacement(BlockItemUseContext context) { protected Direction getFacingForPlacement(BlockItemUseContext context) {
return context.getFace(); return context.getFace();

View file

@ -269,6 +269,7 @@
"death.attack.create.cuckoo_clock_explosion": "%1$s was blown up by tampered cuckoo clock", "death.attack.create.cuckoo_clock_explosion": "%1$s was blown up by tampered cuckoo clock",
"create.recipe.crushing": "Crushing", "create.recipe.crushing": "Crushing",
"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.smokingViaFan": "Bulk Smoking",
@ -400,6 +401,7 @@
"create.gui.stress_gauge.no_rotation": "No Rotation", "create.gui.stress_gauge.no_rotation": "No Rotation",
"create.gui.contraptions.not_fast_enough": "It appears that this %1$s is _not_ rotating with _enough_ _speed_.", "create.gui.contraptions.not_fast_enough": "It appears that this %1$s is _not_ rotating with _enough_ _speed_.",
"create.gui.contraptions.network_overstressed": "It appears that this contraption is _overstressed_. Add more sources or _slow_ _down_ the components with a high _stress_ _impact_.",
"create.gui.flexcrate.title": "Adjustable Crate", "create.gui.flexcrate.title": "Adjustable Crate",
"create.gui.flexcrate.storageSpace": "Storage Space", "create.gui.flexcrate.storageSpace": "Storage Space",
@ -850,6 +852,11 @@
"block.create.turntable.tooltip": "TURNTABLE", "block.create.turntable.tooltip": "TURNTABLE",
"block.create.turntable.tooltip.summary": "Turns _Rotational_ _Force_ into refined Motion Sickness.", "block.create.turntable.tooltip.summary": "Turns _Rotational_ _Force_ into refined Motion Sickness.",
"block.create.millstone.tooltip": "MILLSTONE",
"block.create.millstone.tooltip.summary": "A kinetic component suitable for _grinding_ inserted _materials_. Can be powered by an adjacent cogwheel or by connecting to the shaft at the bottom.",
"block.create.millstone.tooltip.condition1": "When Rotated",
"block.create.millstone.tooltip.behaviour1": "Starts applying _milling_ _recipes_ to any items inserted from the side or the top of the block.",
"block.create.crushing_wheel.tooltip": "CRUSHING WHEEL", "block.create.crushing_wheel.tooltip": "CRUSHING WHEEL",
"block.create.crushing_wheel.tooltip.summary": "Large rotatable wheels that _break_ _down_ anything.", "block.create.crushing_wheel.tooltip.summary": "Large rotatable wheels that _break_ _down_ anything.",
"block.create.crushing_wheel.tooltip.condition1": "When attached to other Crushing Wheel", "block.create.crushing_wheel.tooltip.condition1": "When attached to other Crushing Wheel",

View file

@ -83,7 +83,9 @@
"north": {"uv": [1, 1.5, 5, 5], "texture": "#5"}, "north": {"uv": [1, 1.5, 5, 5], "texture": "#5"},
"east": {"uv": [1, 1.5, 5, 5], "texture": "#5"}, "east": {"uv": [1, 1.5, 5, 5], "texture": "#5"},
"south": {"uv": [1, 1.5, 5, 5], "texture": "#5"}, "south": {"uv": [1, 1.5, 5, 5], "texture": "#5"},
"west": {"uv": [1, 1.5, 5, 5], "texture": "#5"} "west": {"uv": [1, 1.5, 5, 5], "texture": "#5"},
"up": {"uv": [1, 1, 5, 5], "texture": "#5"},
"down": {"uv": [1, 1, 5, 5], "texture": "#5"}
} }
}, },
{ {

View file

@ -1,29 +0,0 @@
{
"type": "crafting_shaped",
"pattern": [
"ABA",
"BSB",
"ABA"
],
"key": {
"B": {
"item": "minecraft:polished_andesite"
},
"A": {
"item": "create:andesite_alloy"
},
"S": {
"item": "create:large_cogwheel"
}
},
"result": {
"item": "create:crushing_wheel",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -1,5 +1,5 @@
{ {
"type": "create:milling", "type": "create:crushing",
"ingredients": [ "ingredients": [
{ {
"item": "minecraft:diamond_horse_armor" "item": "minecraft:diamond_horse_armor"

View file

@ -1,5 +1,5 @@
{ {
"type": "create:milling", "type": "create:crushing",
"ingredients": [ "ingredients": [
{ {
"item": "minecraft:golden_horse_armor" "item": "minecraft:golden_horse_armor"

View file

@ -0,0 +1,25 @@
{
"type": "create:crushing",
"ingredients": [
{
"item": "minecraft:gravel"
}
],
"results": [
{
"item": "minecraft:sand",
"count": 1
},
{
"item": "minecraft:clay_ball",
"count": 1,
"chance": 0.1
},
{
"item": "minecraft:flint",
"count": 1,
"chance": 0.2
}
],
"processingTime": 250
}

View file

@ -1,5 +1,5 @@
{ {
"type": "create:milling", "type": "create:crushing",
"ingredients": [ "ingredients": [
{ {
"item": "minecraft:iron_horse_armor" "item": "minecraft:iron_horse_armor"

View file

@ -1,5 +1,5 @@
{ {
"type": "create:milling", "type": "create:crushing",
"ingredients": [ "ingredients": [
{ {
"item": "minecraft:leather_horse_armor" "item": "minecraft:leather_horse_armor"

View file

@ -0,0 +1,25 @@
{
"type": "create:crushing",
"ingredients": [
{
"item": "minecraft:sand"
}
],
"results": [
{
"item": "create:limesand",
"count": 1
},
{
"item": "create:limesand",
"count": 1,
"chance": 0.5
},
{
"item": "minecraft:bone_meal",
"count": 1,
"chance": 0.05
}
],
"processingTime": 150
}

View file

@ -0,0 +1,34 @@
{
"type": "create:mechanical_crafting",
"pattern": [
" PPP ",
"PSBSP",
"PBCBP",
"PSBSP",
" PPP "
],
"key": {
"P": {
"item": "create:andesite_alloy"
},
"S": {
"tag": "forge:rods/wooden"
},
"C": {
"item": "create:andesite_casing"
},
"B": {
"tag": "forge:stone"
}
},
"result": {
"item": "create:crushing_wheel",
"count": 2
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -14,11 +14,6 @@
"item": "minecraft:clay_ball", "item": "minecraft:clay_ball",
"count": 1, "count": 1,
"chance": 0.5 "chance": 0.5
},
{
"item": "minecraft:flint",
"count": 1,
"chance": 0.2
} }
], ],
"processingTime": 50 "processingTime": 50

View file

@ -0,0 +1,15 @@
{
"type": "create:milling",
"ingredients": [
{
"tag": "forge:ores/copper"
}
],
"results": [
{
"item": "create:crushed_copper",
"count": 1
}
],
"processingTime": 350
}

View file

@ -0,0 +1,15 @@
{
"type": "create:milling",
"ingredients": [
{
"tag": "forge:ores/gold"
}
],
"results": [
{
"item": "create:crushed_gold",
"count": 1
}
],
"processingTime": 350
}

View file

@ -6,19 +6,9 @@
} }
], ],
"results": [ "results": [
{
"item": "minecraft:sand",
"count": 1
},
{
"item": "minecraft:clay_ball",
"count": 1,
"chance": 0.1
},
{ {
"item": "minecraft:flint", "item": "minecraft:flint",
"count": 1, "count": 1
"chance": 0.2
} }
], ],
"processingTime": 250 "processingTime": 250

View file

@ -0,0 +1,15 @@
{
"type": "create:milling",
"ingredients": [
{
"tag": "forge:ores/iron"
}
],
"results": [
{
"item": "create:crushed_iron",
"count": 1
}
],
"processingTime": 400
}

View file

@ -9,16 +9,6 @@
{ {
"item": "create:limesand", "item": "create:limesand",
"count": 1 "count": 1
},
{
"item": "create:limesand",
"count": 1,
"chance": 0.5
},
{
"item": "minecraft:bone_meal",
"count": 1,
"chance": 0.05
} }
], ],
"processingTime": 150 "processingTime": 150

View file

@ -0,0 +1,15 @@
{
"type": "create:milling",
"ingredients": [
{
"tag": "forge:ores/zinc"
}
],
"results": [
{
"item": "create:crushed_zinc",
"count": 1
}
],
"processingTime": 350
}