Playtest Issues, Part III

- Made /KillTPS unavailable for release dist
- Shafts now place correctly again
- Doors and Pressure Plates are now portable
- Fixed crash when using the Mechanical Saw for item processing
- Belts and other item insertion can now insert into crushing wheels directly
This commit is contained in:
simibubi 2020-03-16 21:40:15 +01:00
parent 1edda9b564
commit f26c80560d
15 changed files with 187 additions and 175 deletions

View file

@ -7,12 +7,8 @@ import net.minecraft.command.Commands;
public class CreateCommand { public class CreateCommand {
public CreateCommand(CommandDispatcher<CommandSource> dispatcher){ public CreateCommand(CommandDispatcher<CommandSource> dispatcher) {
// KillTPSCommand.register(dispatcher); Commented out for release
KillTPSCommand.register(dispatcher); dispatcher.register(Commands.literal("create").then(ToggleDebugCommand.register()));
dispatcher.register(Commands.literal("create")
.then(ToggleDebugCommand.register())
);
} }
} }

View file

@ -10,58 +10,59 @@ import net.minecraft.command.Commands;
public class KillTPSCommand { public class KillTPSCommand {
public static void register(CommandDispatcher<CommandSource> dispatcher) { public static void register(CommandDispatcher<CommandSource> dispatcher) {
dispatcher.register( dispatcher.register(Commands.literal(Lang.translate("command.killTPSCommand"))
Commands.literal(Lang.translate("command.killTPSCommand")) .requires(cs -> cs.hasPermissionLevel(2)).executes(ctx -> {
.requires(cs -> cs.hasPermissionLevel(2)) // killtps no arguments
.executes(ctx -> { ctx.getSource().sendFeedback(
//killtps no arguments Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.0",
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.0", Create.lagger.isLagging() ? Create.lagger.getTickTime() : 0), true); Create.lagger.isLagging() ? Create.lagger.getTickTime() : 0),
if (Create.lagger.isLagging()) true);
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"), true); if (Create.lagger.isLagging())
else ctx.getSource().sendFeedback(
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.1"),true); Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"), true);
else
ctx.getSource().sendFeedback(
Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.1"), true);
return 1; return 1;
}) }).then(Commands.literal("start").executes(ctx -> {
.then(Commands.literal("start") // killtps start no time
.executes(ctx -> {
//killtps start no time
int tickTime = Create.lagger.getTickTime(); int tickTime = Create.lagger.getTickTime();
if (tickTime > 0){ if (tickTime > 0) {
Create.lagger.setLagging(true); Create.lagger.setLagging(true);
ctx.getSource().sendFeedback((Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.1", tickTime)),true); ctx.getSource().sendFeedback((Lang
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"),true); .createTranslationTextComponent("command.killTPSCommand.status.slowed_by.1", tickTime)),
true);
ctx.getSource().sendFeedback(
Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"), true);
} else { } else {
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.1"),true); ctx.getSource().sendFeedback(
Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.1"), true);
} }
return 1; return 1;
}) }).then(Commands.argument(Lang.translate("command.killTPSCommand.argument.tickTime"),
.then(Commands.argument(Lang.translate("command.killTPSCommand.argument.tickTime"), IntegerArgumentType.integer(1)) IntegerArgumentType.integer(1)).executes(ctx -> {
.executes(ctx -> { // killtps start tickTime
//killtps start tickTime int tickTime = IntegerArgumentType.getInteger(ctx,
int tickTime = IntegerArgumentType.getInteger(ctx, Lang.translate("command.killTPSCommand.argument.tickTime")); Lang.translate("command.killTPSCommand.argument.tickTime"));
Create.lagger.setTickTime(tickTime); Create.lagger.setTickTime(tickTime);
Create.lagger.setLagging(true); Create.lagger.setLagging(true);
ctx.getSource().sendFeedback((Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.1", tickTime)),true); ctx.getSource().sendFeedback((Lang.createTranslationTextComponent(
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"),true); "command.killTPSCommand.status.slowed_by.1", tickTime)), true);
ctx.getSource().sendFeedback(
Lang.createTranslationTextComponent("command.killTPSCommand.status.usage.0"), true);
return 1; return 1;
}) })))
) .then(Commands.literal("stop").executes(ctx -> {
) // killtps stop
.then(Commands.literal("stop")
.executes(ctx -> {
//killtps stop
Create.lagger.setLagging(false); Create.lagger.setLagging(false);
ctx.getSource().sendFeedback(Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.2"), false); ctx.getSource().sendFeedback(
Lang.createTranslationTextComponent("command.killTPSCommand.status.slowed_by.2"), false);
return 1; return 1;
}) })));
)
);
} }
} }

View file

@ -68,8 +68,8 @@ public abstract class RotatedPillarKineticBlock extends KineticBlock {
Axis preferredAxis = getPreferredAxis(context); Axis preferredAxis = getPreferredAxis(context);
if (preferredAxis != null && !context.isPlacerSneaking()) if (preferredAxis != null && !context.isPlacerSneaking())
return this.getDefaultState().with(AXIS, preferredAxis); return this.getDefaultState().with(AXIS, preferredAxis);
return this.getDefaultState().with(AXIS, return this.getDefaultState().with(AXIS, context.isPlacerSneaking() ? context.getFace().getAxis()
preferredAxis == null ? context.getFace().getAxis() : context.getNearestLookingDirection().getAxis()); : context.getNearestLookingDirection().getAxis());
} }
@Override @Override

View file

@ -5,10 +5,12 @@ import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import net.minecraft.block.AbstractPressurePlateBlock;
import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.AbstractRailBlock;
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.DoorBlock;
import net.minecraft.block.HorizontalFaceBlock; import net.minecraft.block.HorizontalFaceBlock;
import net.minecraft.block.LadderBlock; import net.minecraft.block.LadderBlock;
import net.minecraft.block.RedstoneWallTorchBlock; import net.minecraft.block.RedstoneWallTorchBlock;
@ -59,6 +61,10 @@ public class BlockMovementTraits {
return true; return true;
if (block instanceof TorchBlock) if (block instanceof TorchBlock)
return true; return true;
if (block instanceof AbstractPressurePlateBlock)
return true;
if (block instanceof DoorBlock)
return true;
if (block instanceof HorizontalFaceBlock) if (block instanceof HorizontalFaceBlock)
return true; return true;
if (block instanceof AbstractRailBlock) if (block instanceof AbstractRailBlock)
@ -75,6 +81,10 @@ public class BlockMovementTraits {
return state.get(LadderBlock.FACING) == direction.getOpposite(); return state.get(LadderBlock.FACING) == direction.getOpposite();
if (block instanceof WallTorchBlock) if (block instanceof WallTorchBlock)
return state.get(WallTorchBlock.HORIZONTAL_FACING) == direction.getOpposite(); return state.get(WallTorchBlock.HORIZONTAL_FACING) == direction.getOpposite();
if (block instanceof AbstractPressurePlateBlock)
return direction == Direction.DOWN;
if (block instanceof DoorBlock)
return direction == Direction.DOWN;
if (block instanceof RedstoneWallTorchBlock) if (block instanceof RedstoneWallTorchBlock)
return state.get(RedstoneWallTorchBlock.FACING) == direction.getOpposite(); return state.get(RedstoneWallTorchBlock.FACING) == direction.getOpposite();
if (block instanceof TorchBlock) if (block instanceof TorchBlock)

View file

@ -35,11 +35,13 @@ 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.ChestBlock; import net.minecraft.block.ChestBlock;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.SlimeBlock; import net.minecraft.block.SlimeBlock;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.ChestType; import net.minecraft.state.properties.ChestType;
import net.minecraft.state.properties.DoubleBlockHalf;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@ -157,6 +159,11 @@ public abstract class Contraption {
if (prevPos != null && !visited.contains(prevPos)) if (prevPos != null && !visited.contains(prevPos))
frontier.add(prevPos); frontier.add(prevPos);
} }
if (state.getBlock() instanceof DoorBlock) {
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
if (!visited.contains(otherPartPos))
frontier.add(otherPartPos);
}
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock; boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
for (Direction offset : Direction.values()) { for (Direction offset : Direction.values()) {
@ -388,7 +395,8 @@ public abstract class Contraption {
if (customRemoval.test(add, block.state)) if (customRemoval.test(add, block.state))
continue; continue;
world.getWorld().removeTileEntity(add); world.getWorld().removeTileEntity(add);
world.setBlockState(add, Blocks.AIR.getDefaultState(), 67); int flags = 67 | 32 | 16;
world.setBlockState(add, Blocks.AIR.getDefaultState(), flags);
} }
} }
} }
@ -410,9 +418,11 @@ public abstract class Contraption {
if (customPlacement.test(targetPos, state)) if (customPlacement.test(targetPos, state))
continue; continue;
for (Direction face : Direction.values()) if (nonBrittles)
state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, for (Direction face : Direction.values())
targetPos, targetPos.offset(face)); state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world,
targetPos, targetPos.offset(face));
if (AllBlocks.SAW.typeOf(state)) if (AllBlocks.SAW.typeOf(state))
state = state.with(SawBlock.RUNNING, false); state = state.with(SawBlock.RUNNING, false);

View file

@ -4,14 +4,14 @@ import java.util.List;
import com.simibubi.create.AllRecipes; import com.simibubi.create.AllRecipes;
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient; import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.modules.contraptions.processing.ProcessingInventory;
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class CrushingRecipe extends ProcessingRecipe<ProcessingInventory> { public class CrushingRecipe extends ProcessingRecipe<RecipeWrapper> {
public CrushingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients, public CrushingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) { List<ProcessingOutput> results, int processingDuration) {
@ -19,7 +19,7 @@ public class CrushingRecipe extends ProcessingRecipe<ProcessingInventory> {
} }
@Override @Override
public boolean matches(ProcessingInventory inv, World worldIn) { public boolean matches(RecipeWrapper inv, World worldIn) {
if (inv.isEmpty()) if (inv.isEmpty())
return false; return false;
return ingredients.get(0).test(inv.getStackInSlot(0)); return ingredients.get(0).test(inv.getStackInSlot(0));

View file

@ -176,7 +176,7 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
if (worldIn.getTileEntity(pos) == null) if (worldIn.getTileEntity(pos) == null)
return; return;
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos); CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos);
for (int slot = 0; slot < te.inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < te.inventory.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inventory.getStackInSlot(slot)); te.inventory.getStackInSlot(slot));
} }

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.contraptions.components.crusher; package com.simibubi.create.modules.contraptions.components.crusher;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
@ -9,6 +10,7 @@ import com.simibubi.create.AllRecipes;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.block.SyncedTileEntity; import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.processing.ProcessingInventory; import com.simibubi.create.modules.contraptions.processing.ProcessingInventory;
@ -23,9 +25,15 @@ import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ItemParticleData; import net.minecraft.particles.ItemParticleData;
import net.minecraft.particles.ParticleTypes; import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class CrushingWheelControllerTileEntity extends SyncedTileEntity implements ITickableTileEntity { public class CrushingWheelControllerTileEntity extends SyncedTileEntity implements ITickableTileEntity {
@ -34,11 +42,21 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
protected boolean searchForEntity; protected boolean searchForEntity;
public ProcessingInventory inventory; public ProcessingInventory inventory;
protected LazyOptional<IItemHandlerModifiable> handler = LazyOptional.of(() -> inventory);
private RecipeWrapper wrapper;
public float crushingspeed; public float crushingspeed;
public CrushingWheelControllerTileEntity() { public CrushingWheelControllerTileEntity() {
super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type); super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type);
inventory = new ProcessingInventory(); inventory = new ProcessingInventory(this::itemInserted) {
@Override
public boolean isItemValid(int slot, ItemStack stack) {
return super.isItemValid(slot, stack) && processingEntity == null;
}
};
wrapper = new RecipeWrapper(inventory);
} }
@Override @Override
@ -82,7 +100,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
} }
if (inventory.remainingTime <= 0) { if (inventory.remainingTime <= 0) {
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < inventory.getSlots(); slot++) {
ItemStack stack = inventory.getStackInSlot(slot); ItemStack stack = inventory.getStackInSlot(slot);
if (stack.isEmpty()) if (stack.isEmpty())
continue; continue;
@ -127,7 +145,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
ItemEntity itemEntity = (ItemEntity) processingEntity; ItemEntity itemEntity = (ItemEntity) processingEntity;
itemEntity.setPickupDelay(20); itemEntity.setPickupDelay(20);
if (processingEntity.posY < pos.getY() + .25f) { if (processingEntity.posY < pos.getY() + .25f) {
insertItem(itemEntity); inventory.clear();
inventory.setStackInSlot(0, itemEntity.getItem().copy());
itemInserted(inventory.getStackInSlot(0));
itemEntity.remove(); itemEntity.remove();
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16); world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
} }
@ -140,8 +160,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
IParticleData particleData = null; IParticleData particleData = null;
if (stack.getItem() instanceof BlockItem) if (stack.getItem() instanceof BlockItem)
particleData = new BlockParticleData(ParticleTypes.BLOCK, particleData =
((BlockItem) stack.getItem()).getBlock().getDefaultState()); new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
else else
particleData = new ItemParticleData(ParticleTypes.ITEM, stack); particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
@ -152,28 +172,22 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
} }
private void applyRecipe() { private void applyRecipe() {
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.CRUSHING.getType(), inventory, Optional<CrushingRecipe> recipe =
world); world.getRecipeManager().getRecipe(AllRecipes.CRUSHING.getType(), wrapper, world);
List<ItemStack> list = new ArrayList<>();
if (recipe.isPresent()) { if (recipe.isPresent()) {
int rolls = inventory.getStackInSlot(0).getCount(); int rolls = inventory.getStackInSlot(0).getCount();
inventory.clear(); inventory.clear();
for (int roll = 0; roll < rolls; roll++) { for (int roll = 0; roll < rolls; roll++) {
List<ItemStack> rolledResults = recipe.get().rollResults(); List<ItemStack> rolledResults = recipe.get().rollResults();
for (int i = 0; i < rolledResults.size(); i++) { for (int i = 0; i < rolledResults.size(); i++) {
ItemStack stack = rolledResults.get(i); ItemStack stack = rolledResults.get(i);
ItemHelper.addToList(stack, list);
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
stack = inventory.getItems().insertItem(slot, stack, false);
if (stack.isEmpty())
break;
}
} }
} }
for (int slot = 0; slot < list.size() && slot + 1 < inventory.getSlots(); slot++)
inventory.setStackInSlot(slot + 1, list.get(slot));
} else { } else {
inventory.clear(); inventory.clear();
} }
@ -184,7 +198,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
if (hasEntity() && !isFrozen()) if (hasEntity() && !isFrozen())
compound.put("Entity", NBTUtil.writeUniqueId(entityUUID)); compound.put("Entity", NBTUtil.writeUniqueId(entityUUID));
inventory.write(compound); compound.put("Inventory", inventory.serializeNBT());
compound.putFloat("Speed", crushingspeed); compound.putFloat("Speed", crushingspeed);
return super.write(compound); return super.write(compound);
@ -199,8 +213,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
this.searchForEntity = true; this.searchForEntity = true;
} }
crushingspeed = compound.getFloat("Speed"); crushingspeed = compound.getFloat("Speed");
inventory = ProcessingInventory.read(compound); inventory.deserializeNBT(compound.getCompound("Inventory"));
} }
public void startCrushing(Entity entity) { public void startCrushing(Entity entity) {
@ -208,16 +221,20 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
entityUUID = entity.getUniqueID(); entityUUID = entity.getUniqueID();
} }
private void insertItem(ItemEntity entity) { private void itemInserted(ItemStack stack) {
inventory.clear(); Optional<CrushingRecipe> recipe =
inventory.setInventorySlotContents(0, entity.getItem()); world.getRecipeManager().getRecipe(AllRecipes.CRUSHING.getType(), wrapper, world);
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.CRUSHING.getType(), inventory,
world);
inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100; inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
inventory.appliedRecipe = false; inventory.appliedRecipe = false;
} }
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return handler.cast();
return super.getCapability(cap, side);
}
public void clear() { public void clear() {
processingEntity = null; processingEntity = null;
entityUUID = null; entityUUID = null;

View file

@ -4,14 +4,14 @@ import java.util.List;
import com.simibubi.create.AllRecipes; import com.simibubi.create.AllRecipes;
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient; import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.modules.contraptions.processing.ProcessingInventory;
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class CuttingRecipe extends ProcessingRecipe<ProcessingInventory> { public class CuttingRecipe extends ProcessingRecipe<RecipeWrapper> {
public CuttingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients, public CuttingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) { List<ProcessingOutput> results, int processingDuration) {
@ -19,7 +19,7 @@ public class CuttingRecipe extends ProcessingRecipe<ProcessingInventory> {
} }
@Override @Override
public boolean matches(ProcessingInventory inv, World worldIn) { public boolean matches(RecipeWrapper inv, World worldIn) {
if (inv.isEmpty()) if (inv.isEmpty())
return false; return false;
return ingredients.get(0).test(inv.getStackInSlot(0)); return ingredients.get(0).test(inv.getStackInSlot(0));

View file

@ -129,7 +129,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
withTileEntityDo(worldIn, pos, te -> { withTileEntityDo(worldIn, pos, te -> {
for (int slot = 0; slot < te.inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < te.inventory.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inventory.getStackInSlot(slot)); te.inventory.getStackInSlot(slot));
} }

View file

@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.components.saw;
import static com.simibubi.create.modules.contraptions.components.saw.SawBlock.RUNNING; import static com.simibubi.create.modules.contraptions.components.saw.SawBlock.RUNNING;
import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@ -12,6 +13,7 @@ import com.simibubi.create.AllRecipes;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.TreeCutter; import com.simibubi.create.foundation.utility.TreeCutter;
import com.simibubi.create.foundation.utility.TreeCutter.Tree; import com.simibubi.create.foundation.utility.TreeCutter.Tree;
@ -37,7 +39,6 @@ import net.minecraft.particles.ParticleTypes;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
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.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -57,7 +58,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
public SawTileEntity() { public SawTileEntity() {
super(AllTileEntities.SAW.type); super(AllTileEntities.SAW.type);
inventory = new ProcessingInventory(); inventory = new ProcessingInventory(this::start);
inventory.remainingTime = -1; inventory.remainingTime = -1;
recipeIndex = 0; recipeIndex = 0;
invProvider = LazyOptional.of(() -> inventory); invProvider = LazyOptional.of(() -> inventory);
@ -86,7 +87,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
inventory.write(compound); compound.put("Inventory", inventory.serializeNBT());
compound.putInt("RecipeIndex", recipeIndex); compound.putInt("RecipeIndex", recipeIndex);
return super.write(compound); return super.write(compound);
} }
@ -94,7 +95,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
super.read(compound); super.read(compound);
inventory = ProcessingInventory.read(compound); inventory.deserializeNBT(compound.getCompound("Inventory"));
recipeIndex = compound.getInt("RecipeIndex"); recipeIndex = compound.getInt("RecipeIndex");
} }
@ -110,7 +111,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return; return;
if (inventory.remainingTime == -1) { if (inventory.remainingTime == -1) {
if (!inventory.isEmpty() && !inventory.appliedRecipe) if (!inventory.isEmpty() && !inventory.appliedRecipe)
start(); start(inventory.getStackInSlot(0));
return; return;
} }
@ -142,15 +143,15 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
if (AllBlocks.BELT.typeOf(world.getBlockState(nextPos))) { if (AllBlocks.BELT.typeOf(world.getBlockState(nextPos))) {
TileEntity te = world.getTileEntity(nextPos); TileEntity te = world.getTileEntity(nextPos);
if (te != null && te instanceof BeltTileEntity) { if (te != null && te instanceof BeltTileEntity) {
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < inventory.getSlots(); slot++) {
ItemStack stack = inventory.getStackInSlot(slot); ItemStack stack = inventory.getStackInSlot(slot);
if (stack.isEmpty()) if (stack.isEmpty())
continue; continue;
if (itemMovementFacing.getAxis() == Axis.Z) // if (itemMovementFacing.getAxis() == Axis.Z)
itemMovementFacing = itemMovementFacing.getOpposite(); // itemMovementFacing = itemMovementFacing.getOpposite();
if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false)) if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false))
inventory.setInventorySlotContents(slot, ItemStack.EMPTY); inventory.setStackInSlot(slot, ItemStack.EMPTY);
else { else {
inventory.remainingTime = 0; inventory.remainingTime = 0;
return; return;
@ -170,7 +171,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
Vec3d otherMovement = sawTileEntity.getItemMovementVec(); Vec3d otherMovement = sawTileEntity.getItemMovementVec();
if (Direction.getFacingFromVector(otherMovement.x, otherMovement.y, if (Direction.getFacingFromVector(otherMovement.x, otherMovement.y,
otherMovement.z) != itemMovementFacing.getOpposite()) { otherMovement.z) != itemMovementFacing.getOpposite()) {
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < inventory.getSlots(); slot++) {
ItemStack stack = inventory.getStackInSlot(slot); ItemStack stack = inventory.getStackInSlot(slot);
if (stack.isEmpty()) if (stack.isEmpty())
continue; continue;
@ -178,7 +179,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
ProcessingInventory sawInv = sawTileEntity.inventory; ProcessingInventory sawInv = sawTileEntity.inventory;
if (sawInv.isEmpty()) { if (sawInv.isEmpty()) {
sawInv.insertItem(0, stack, false); sawInv.insertItem(0, stack, false);
inventory.setInventorySlotContents(slot, ItemStack.EMPTY); inventory.setStackInSlot(slot, ItemStack.EMPTY);
} else { } else {
inventory.remainingTime = 0; inventory.remainingTime = 0;
@ -193,7 +194,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
} }
// Eject Items // Eject Items
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { for (int slot = 0; slot < inventory.getSlots(); slot++) {
ItemStack stack = inventory.getStackInSlot(slot); ItemStack stack = inventory.getStackInSlot(slot);
if (stack.isEmpty()) if (stack.isEmpty())
continue; continue;
@ -231,8 +232,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
IParticleData particleData = null; IParticleData particleData = null;
float speed = 1; float speed = 1;
if (stack.getItem() instanceof BlockItem) if (stack.getItem() instanceof BlockItem)
particleData = new BlockParticleData(ParticleTypes.BLOCK, particleData =
((BlockItem) stack.getItem()).getBlock().getDefaultState()); new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
else { else {
particleData = new ItemParticleData(ParticleTypes.ITEM, stack); particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
speed = .125f; speed = .125f;
@ -265,6 +266,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
int rolls = inventory.getStackInSlot(0).getCount(); int rolls = inventory.getStackInSlot(0).getCount();
inventory.clear(); inventory.clear();
List<ItemStack> list = new ArrayList<>();
for (int roll = 0; roll < rolls; roll++) { for (int roll = 0; roll < rolls; roll++) {
List<ItemStack> results = new LinkedList<ItemStack>(); List<ItemStack> results = new LinkedList<ItemStack>();
if (recipe instanceof CuttingRecipe) if (recipe instanceof CuttingRecipe)
@ -274,15 +276,11 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
for (int i = 0; i < results.size(); i++) { for (int i = 0; i < results.size(); i++) {
ItemStack stack = results.get(i); ItemStack stack = results.get(i);
ItemHelper.addToList(stack, list);
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
stack = inventory.getItems().insertItem(slot, stack, false);
if (stack.isEmpty())
break;
}
} }
} }
for (int slot = 0; slot < list.size() && slot + 1 < inventory.getSlots(); slot++)
inventory.setStackInSlot(slot + 1, list.get(slot));
} }
@ -303,12 +301,11 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return; return;
inventory.clear(); inventory.clear();
inventory.setInventorySlotContents(0, entity.getItem().copy()); inventory.insertItem(0, entity.getItem().copy(), false);
entity.remove(); entity.remove();
start();
} }
public void start() { public void start(ItemStack inserted) {
if (!canProcess()) if (!canProcess())
return; return;
if (inventory.isEmpty()) if (inventory.isEmpty())
@ -338,7 +335,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
time = ((CuttingRecipe) recipe).getProcessingDuration(); time = ((CuttingRecipe) recipe).getProcessingDuration();
} }
inventory.remainingTime = time * Math.max(1, (inventory.getStackInSlot(0).getCount() / 5)); inventory.remainingTime = time * Math.max(1, (inserted.getCount() / 5));
inventory.recipeDuration = inventory.remainingTime; inventory.recipeDuration = inventory.remainingTime;
inventory.appliedRecipe = false; inventory.appliedRecipe = false;
sendData(); sendData();

View file

@ -40,7 +40,7 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
sendData(); sendData();
markDirty(); markDirty();
}; };
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
for (int i = 0; i < getSlots(); i++) { for (int i = 0; i < getSlots(); i++) {
ItemStack stackInSlot = getStackInSlot(i); ItemStack stackInSlot = getStackInSlot(i);
@ -85,8 +85,8 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
} }
protected LazyOptional<IItemHandlerModifiable> inventory = LazyOptional protected LazyOptional<IItemHandlerModifiable> inventory =
.of(() -> new BasinInventory(inputInventory, outputInventory)); LazyOptional.of(() -> new BasinInventory(inputInventory, outputInventory));
public BasinInputInventory recipeInventory; public BasinInputInventory recipeInventory;
public BasinTileEntity() { public BasinTileEntity() {

View file

@ -1,75 +1,60 @@
package com.simibubi.create.modules.contraptions.processing; package com.simibubi.create.modules.contraptions.processing;
import net.minecraft.inventory.ItemStackHelper; import java.util.function.Consumer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.NonNullList;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class ProcessingInventory extends RecipeWrapper implements IItemHandler { public class ProcessingInventory extends ItemStackHandler {
public float remainingTime; public float remainingTime;
public float recipeDuration; public float recipeDuration;
public boolean appliedRecipe; public boolean appliedRecipe;
public Consumer<ItemStack> callback;
public ProcessingInventory() { public ProcessingInventory(Consumer<ItemStack> callback) {
super(new ItemStackHandler(10)); super(10);
this.callback = callback;
} }
@Override
public void clear() { public void clear() {
super.clear(); for (int i = 0; i < getSlots(); i++)
setStackInSlot(i, ItemStack.EMPTY);
remainingTime = 0; remainingTime = 0;
recipeDuration = 0; recipeDuration = 0;
appliedRecipe = false; appliedRecipe = false;
} }
public void write(CompoundNBT nbt) { public boolean isEmpty() {
NonNullList<ItemStack> stacks = NonNullList.create(); for (int i = 0; i < getSlots(); i++)
for (int slot = 0; slot < inv.getSlots(); slot++) { if (!getStackInSlot(i).isEmpty())
ItemStack stack = inv.getStackInSlot(slot); return false;
stacks.add(stack); return true;
}
ItemStackHelper.saveAllItems(nbt, stacks);
nbt.putFloat("ProcessingTime", remainingTime);
nbt.putFloat("RecipeTime", recipeDuration);
nbt.putBoolean("AppliedRecipe", appliedRecipe);
}
public static ProcessingInventory read(CompoundNBT nbt) {
ProcessingInventory inventory = new ProcessingInventory();
NonNullList<ItemStack> stacks = NonNullList.withSize(10, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(nbt, stacks);
for (int slot = 0; slot < stacks.size(); slot++)
inventory.setInventorySlotContents(slot, stacks.get(slot));
inventory.remainingTime = nbt.getFloat("ProcessingTime");
inventory.recipeDuration = nbt.getFloat("RecipeTime");
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
return inventory;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
public ItemStackHandler getItems() {
return (ItemStackHandler) inv;
}
@Override
public int getSlots() {
return 9;
} }
@Override @Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (!isItemValid(slot, stack)) ItemStack insertItem = super.insertItem(slot, stack, simulate);
return stack; if (slot == 0 && !insertItem.equals(stack, true))
return inv.insertItem(slot, stack, simulate); callback.accept(insertItem.copy());
return insertItem;
}
@Override
public CompoundNBT serializeNBT() {
CompoundNBT nbt = super.serializeNBT();
nbt.putFloat("ProcessingTime", remainingTime);
nbt.putFloat("RecipeTime", recipeDuration);
nbt.putBoolean("AppliedRecipe", appliedRecipe);
return nbt;
}
@Override
public void deserializeNBT(CompoundNBT nbt) {
remainingTime = nbt.getFloat("ProcessingTime");
recipeDuration = nbt.getFloat("RecipeTime");
appliedRecipe = nbt.getBoolean("AppliedRecipe");
super.deserializeNBT(nbt);
} }
@Override @Override
@ -77,11 +62,6 @@ public class ProcessingInventory extends RecipeWrapper implements IItemHandler {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
@Override
public int getSlotLimit(int slot) {
return 64;
}
@Override @Override
public boolean isItemValid(int slot, ItemStack stack) { public boolean isItemValid(int slot, ItemStack stack) {
return slot == 0 && isEmpty(); return slot == 0 && isEmpty();

View file

@ -201,7 +201,8 @@ public class BeltInventory {
BlockState state = world.getBlockState(nextPosition); BlockState state = world.getBlockState(nextPosition);
// next block is a basin or a saw // next block is a basin or a saw
if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)) { if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)
|| AllBlocks.CRUSHING_WHEEL_CONTROLLER.typeOf(state)) {
TileEntity te = world.getTileEntity(nextPosition); TileEntity te = world.getTileEntity(nextPosition);
if (te != null) { if (te != null) {
LazyOptional<IItemHandler> optional = LazyOptional<IItemHandler> optional =
@ -400,10 +401,10 @@ public class BeltInventory {
Vec3d vec = VecHelper.getCenterOf(belt.getPos()); Vec3d vec = VecHelper.getCenterOf(belt.getPos());
Vec3d horizontalMovement = new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f); Vec3d horizontalMovement = new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f);
if (slope == Slope.VERTICAL) if (slope == Slope.VERTICAL)
horizontalMovement = Vec3d.ZERO; horizontalMovement = Vec3d.ZERO;
vec = vec.add(horizontalMovement).add(0, verticalMovement, 0); vec = vec.add(horizontalMovement).add(0, verticalMovement, 0);
return vec; return vec;
} }

View file

@ -122,7 +122,7 @@ public class BeltTileEntity extends KineticTileEntity {
public AxisAlignedBB getRenderBoundingBox() { public AxisAlignedBB getRenderBoundingBox() {
if (!isController()) if (!isController())
return super.getRenderBoundingBox(); return super.getRenderBoundingBox();
return super.getRenderBoundingBox().grow(beltLength); return super.getRenderBoundingBox().grow(beltLength + 1);
} }
protected void initializeItemHandler() { protected void initializeItemHandler() {