Bug Fixes and Enhancements

- Fixed Tree fertilizer spawning grass when growing large spruce trees
- Nerfed durability of the Deforester
- Items dropped by a tree cut with a Deforester now 'fall' away from the player
- Blockzappers can now be used together with the Symmetry Wand
- Fixed deployer not looking in the right direction
- You can now put items on Crafters directly
- Tree cutting is less lenient about whether the trunk was fully cut or not
- Fixed filtering not looking past first matched item if said item doesn't have the required amount
This commit is contained in:
simibubi 2020-02-01 14:26:19 +01:00
parent b453e6bb2c
commit 87f61ce538
12 changed files with 92 additions and 23 deletions

View file

@ -99,6 +99,7 @@ public class ItemHelper {
boolean checkHasEnoughItems = amountRequired; boolean checkHasEnoughItems = amountRequired;
boolean hasEnoughItems = !checkHasEnoughItems; boolean hasEnoughItems = !checkHasEnoughItems;
int maxExtractionCount = hasEnoughItems ? CreateConfig.parameters.extractorAmount.get() : exactAmount; int maxExtractionCount = hasEnoughItems ? CreateConfig.parameters.extractorAmount.get() : exactAmount;
boolean potentialOtherMatch = false;
Extraction: do { Extraction: do {
extracting = ItemStack.EMPTY; extracting = ItemStack.EMPTY;
@ -106,10 +107,14 @@ public class ItemHelper {
for (int slot = 0; slot < inv.getSlots(); slot++) { for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stack = inv.extractItem(slot, maxExtractionCount - extracting.getCount(), true); ItemStack stack = inv.extractItem(slot, maxExtractionCount - extracting.getCount(), true);
if (stack.isEmpty())
continue;
if (!test.test(stack)) if (!test.test(stack))
continue; continue;
if (!extracting.isEmpty() && !ItemHandlerHelper.canItemStacksStack(stack, extracting)) if (!extracting.isEmpty() && !ItemHandlerHelper.canItemStacksStack(stack, extracting)) {
potentialOtherMatch = true;
continue; continue;
}
if (extracting.isEmpty()) if (extracting.isEmpty())
extracting = stack.copy(); extracting = stack.copy();
@ -130,10 +135,17 @@ public class ItemHelper {
} }
} }
if (!extracting.isEmpty() && !hasEnoughItems && potentialOtherMatch) {
ItemStack blackListed = extracting.copy();
test = test.and(i -> !ItemHandlerHelper.canItemStacksStack(i, blackListed));
continue;
}
if (checkHasEnoughItems) if (checkHasEnoughItems)
checkHasEnoughItems = false; checkHasEnoughItems = false;
else else
break Extraction; break Extraction;
} while (true); } while (true);
if (amountRequired && extracting.getCount() < exactAmount) if (amountRequired && extracting.getCount() < exactAmount)

View file

@ -44,7 +44,7 @@ public class TreeCutter {
return null; return null;
visited.add(pos); visited.add(pos);
addNeighbours(pos, frontier, visited); BlockPos.getAllInBox(pos.add(-1, 0, -1), pos.add(1, 1, 1)).forEach(p -> frontier.add(new BlockPos(p)));
// Find all logs // Find all logs
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
@ -105,19 +105,24 @@ public class TreeCutter {
private static boolean validateCut(IBlockReader reader, BlockPos pos) { private static boolean validateCut(IBlockReader reader, BlockPos pos) {
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
List<BlockPos> frontier = new LinkedList<>(); List<BlockPos> frontier = new LinkedList<>();
frontier.add(pos);
frontier.add(pos.up()); frontier.add(pos.up());
int posY = pos.getY();
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
BlockPos currentPos = frontier.remove(0); BlockPos currentPos = frontier.remove(0);
visited.add(currentPos); visited.add(currentPos);
boolean lowerLayer = currentPos.getY() == posY;
if (!isLog(reader.getBlockState(currentPos))) if (!isLog(reader.getBlockState(currentPos)))
continue; continue;
if (!pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down()))) if (!lowerLayer && !pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down())))
return false; return false;
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
if (direction.getAxis().isVertical()) if (direction == Direction.DOWN)
continue;
if (direction == Direction.UP && !lowerLayer)
continue; continue;
BlockPos offset = currentPos.offset(direction); BlockPos offset = currentPos.offset(direction);
if (visited.contains(offset)) if (visited.contains(offset))

View file

@ -87,6 +87,11 @@ public class WrappedWorld extends World {
return null; return null;
} }
@Override
public boolean addEntity(Entity entityIn) {
return world.addEntity(entityIn);
}
@Override @Override
public void registerMapData(MapData mapDataIn) { public void registerMapData(MapData mapDataIn) {
} }

View file

@ -35,7 +35,11 @@ import net.minecraft.util.math.Vec3d;
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.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
public class MechanicalCrafterBlock extends HorizontalKineticBlock public class MechanicalCrafterBlock extends HorizontalKineticBlock
implements IWithTileEntity<MechanicalCrafterTileEntity>, IHaveConnectedTextures { implements IWithTileEntity<MechanicalCrafterTileEntity>, IHaveConnectedTextures {
@ -149,7 +153,7 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
return super.onWrenched(state, context); return ActionResultType.PASS;
} }
@Override @Override
@ -170,6 +174,20 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
return true; return true;
} }
if (crafter.phase == Phase.IDLE && !isHand) {
if (worldIn.isRemote)
return true;
LazyOptional<IItemHandler> capability = crafter
.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
if (!capability.isPresent())
return false;
ItemStack remainder = ItemHandlerHelper.insertItem(capability.orElse(new ItemStackHandler()),
heldItem.copy(), false);
if (remainder.getCount() != heldItem.getCount())
player.setHeldItem(handIn, remainder);
return true;
}
ItemStack inSlot = crafter.inventory.getStackInSlot(0); ItemStack inSlot = crafter.inventory.getStackInSlot(0);
if (inSlot.isEmpty()) if (inSlot.isEmpty())
return false; return false;

View file

@ -252,7 +252,7 @@ public class DeployerTileEntity extends KineticTileEntity {
Vec3d rayTarget = center.add(movementVector.scale(5 / 2f - 1 / 64f)); Vec3d rayTarget = center.add(movementVector.scale(5 / 2f - 1 / 64f));
BlockPos clickedPos = pos.offset(direction, 2); BlockPos clickedPos = pos.offset(direction, 2);
player.rotationYaw = AngleHelper.horizontalAngle(direction) + 180; player.rotationYaw = AngleHelper.horizontalAngle(direction);
player.rotationPitch = direction == Direction.UP ? -90 : direction == Direction.DOWN ? 90 : 0; player.rotationPitch = direction == Direction.UP ? -90 : direction == Direction.DOWN ? 90 : 0;
player.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z); player.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z);
@ -379,10 +379,6 @@ public class DeployerTileEntity extends KineticTileEntity {
ActionResultType onItemUse = stack.onItemUse(itemusecontext); ActionResultType onItemUse = stack.onItemUse(itemusecontext);
if (onItemUse == ActionResultType.SUCCESS) if (onItemUse == ActionResultType.SUCCESS)
return; return;
// some items use hard-coded eye positions
if (item == Items.SNOWBALL || item == Items.EGG)
player.posY -= 1.5f;
if (item == Items.ENDER_PEARL) if (item == Items.ENDER_PEARL)
return; return;

View file

@ -1,7 +1,6 @@
package com.simibubi.create.modules.contraptions.relays.elementary; package com.simibubi.create.modules.contraptions.relays.elementary;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.Debug;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.Block; import net.minecraft.block.Block;

View file

@ -18,6 +18,7 @@ import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.advancements.CriteriaTriggers;
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;
@ -61,6 +62,8 @@ import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
@ -253,9 +256,18 @@ public class BlockzapperItem extends Item {
world.getBlockState(placed.offset(updateDirection)), world, placed, world.getBlockState(placed.offset(updateDirection)), world, placed,
placed.offset(updateDirection)); placed.offset(updateDirection));
BlockSnapshot blocksnapshot = BlockSnapshot.getBlockSnapshot(world, placed);
IFluidState ifluidstate = world.getFluidState(placed); IFluidState ifluidstate = world.getFluidState(placed);
world.setBlockState(placed, ifluidstate.getBlockState(), 18); world.setBlockState(placed, ifluidstate.getBlockState(), 18);
world.setBlockState(placed, stateToUse); world.setBlockState(placed, stateToUse);
if (ForgeEventFactory.onBlockPlace(player, blocksnapshot, Direction.UP)) {
blocksnapshot.restore(true, false);
return new ActionResult<ItemStack>(ActionResultType.FAIL, item);
}
if (player instanceof ServerPlayerEntity)
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, placed,
new ItemStack(stateToUse.getBlock()));
} }

View file

@ -4,15 +4,18 @@ import com.simibubi.create.AllItems;
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;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.curiosities.tools.AllToolTiers; import com.simibubi.create.modules.curiosities.tools.AllToolTiers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.AxeItem; import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
@ -40,15 +43,18 @@ public class DeforesterItem extends AxeItem {
if (world == null) if (world == null)
return; return;
Vec3d vec = player.getLookVec();
for (BlockPos log : tree.logs) for (BlockPos log : tree.logs)
BlockHelper.destroyBlock(world, log, 1 / 2f, item -> { BlockHelper.destroyBlock(world, log, 1 / 2f, item -> {
if (dropBlock) if (dropBlock) {
Block.spawnAsEntity(world, log, item); dropItemFromCutTree(world, pos, vec, log, item);
stack.damageItem(1, player, p -> p.sendBreakAnimation(Hand.MAIN_HAND));
}
}); });
for (BlockPos leaf : tree.leaves) for (BlockPos leaf : tree.leaves)
BlockHelper.destroyBlock(world, leaf, 1 / 8f, item -> { BlockHelper.destroyBlock(world, leaf, 1 / 8f, item -> {
if (dropBlock) if (dropBlock)
Block.spawnAsEntity(world, leaf, item); dropItemFromCutTree(world, pos, vec, leaf, item);
}); });
} }
@ -60,4 +66,13 @@ public class DeforesterItem extends AxeItem {
destroyTree(heldItemMainhand, event.getWorld(), event.getState(), event.getPos(), event.getPlayer()); destroyTree(heldItemMainhand, event.getWorld(), event.getState(), event.getPos(), event.getPlayer());
} }
public static void dropItemFromCutTree(World world, BlockPos breakingPos, Vec3d fallDirection, BlockPos pos,
ItemStack stack) {
float distance = (float) Math.sqrt(pos.distanceSq(breakingPos));
Vec3d dropPos = VecHelper.getCenterOf(pos);
ItemEntity entity = new ItemEntity(world, dropPos.x, dropPos.y, dropPos.z, stack);
entity.setMotion(fallDirection.scale(distance / 20f));
world.addEntity(entity);
}
} }

View file

@ -172,7 +172,8 @@ public class SymmetryWandItem extends Item {
Vec3d mirrorPos = symmetry.getPosition(); Vec3d mirrorPos = symmetry.getPosition();
if (mirrorPos.distanceTo(new Vec3d(pos)) > parameters.maxSymmetryWandRange.get()) if (mirrorPos.distanceTo(new Vec3d(pos)) > parameters.maxSymmetryWandRange.get())
return; return;
if (!player.isCreative() && BlockHelper.findAndRemoveInInventory(block, player, 1) == 0) if (!player.isCreative() && isHoldingBlock(player, block)
&& BlockHelper.findAndRemoveInInventory(block, player, 1) == 0)
return; return;
symmetry.process(blockSet); symmetry.process(blockSet);
@ -213,6 +214,12 @@ public class SymmetryWandItem extends Item {
new SymmetryEffectPacket(to, targets)); new SymmetryEffectPacket(to, targets));
} }
private static boolean isHoldingBlock(PlayerEntity player, BlockState block) {
ItemStack itemBlock = BlockHelper.getRequiredItem(block);
return player.getHeldItemMainhand().isItemEqual(itemBlock)
|| player.getHeldItemOffhand().isItemEqual(itemBlock);
}
public static void remove(World world, ItemStack wand, PlayerEntity player, BlockPos pos) { public static void remove(World world, ItemStack wand, PlayerEntity player, BlockPos pos) {
BlockState air = Blocks.AIR.getDefaultState(); BlockState air = Blocks.AIR.getDefaultState();
BlockState ogBlock = world.getBlockState(pos); BlockState ogBlock = world.getBlockState(pos);

View file

@ -23,7 +23,7 @@ public enum AllToolTiers implements IItemTier {
return Ingredient.fromItems(AllItems.SHADOW_STEEL.item); return Ingredient.fromItems(AllItems.SHADOW_STEEL.item);
}), }),
RADIANT(4, 2303, 16.0F, 3.5F, 10, () -> { RADIANT(4, 1024, 16.0F, 3.5F, 10, () -> {
return Ingredient.fromItems(AllItems.REFINED_RADIANCE.item); return Ingredient.fromItems(AllItems.REFINED_RADIANCE.item);
}), }),

View file

@ -52,8 +52,8 @@ public class TreeFertilizerItem extends Item {
if (!world.getBlockState(pos).isNormalCube(world, pos) if (!world.getBlockState(pos).isNormalCube(world, pos)
&& context.getWorld().getBlockState(actualPos).isNormalCube(context.getWorld(), actualPos)) && context.getWorld().getBlockState(actualPos).isNormalCube(context.getWorld(), actualPos))
continue; continue;
if (world.getBlockState(pos).getBlock() == Blocks.PODZOL if (world.getBlockState(pos).getBlock() == Blocks.GRASS_BLOCK
&& context.getWorld().getBlockState(actualPos).getBlock() != Blocks.GRASS_BLOCK) || world.getBlockState(pos).getBlock() == Blocks.PODZOL)
continue; continue;
context.getWorld().setBlockState(actualPos, world.getBlockState(pos)); context.getWorld().setBlockState(actualPos, world.getBlockState(pos));