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:
parent
b453e6bb2c
commit
87f61ce538
12 changed files with 92 additions and 23 deletions
|
@ -99,17 +99,22 @@ public class ItemHelper {
|
|||
boolean checkHasEnoughItems = amountRequired;
|
||||
boolean hasEnoughItems = !checkHasEnoughItems;
|
||||
int maxExtractionCount = hasEnoughItems ? CreateConfig.parameters.extractorAmount.get() : exactAmount;
|
||||
|
||||
boolean potentialOtherMatch = false;
|
||||
|
||||
Extraction: do {
|
||||
extracting = ItemStack.EMPTY;
|
||||
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stack = inv.extractItem(slot, maxExtractionCount - extracting.getCount(), true);
|
||||
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
if (!test.test(stack))
|
||||
continue;
|
||||
if (!extracting.isEmpty() && !ItemHandlerHelper.canItemStacksStack(stack, extracting))
|
||||
if (!extracting.isEmpty() && !ItemHandlerHelper.canItemStacksStack(stack, extracting)) {
|
||||
potentialOtherMatch = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (extracting.isEmpty())
|
||||
extracting = stack.copy();
|
||||
|
@ -129,11 +134,18 @@ public class ItemHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!extracting.isEmpty() && !hasEnoughItems && potentialOtherMatch) {
|
||||
ItemStack blackListed = extracting.copy();
|
||||
test = test.and(i -> !ItemHandlerHelper.canItemStacksStack(i, blackListed));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkHasEnoughItems)
|
||||
checkHasEnoughItems = false;
|
||||
else
|
||||
break Extraction;
|
||||
|
||||
} while (true);
|
||||
|
||||
if (amountRequired && extracting.getCount() < exactAmount)
|
||||
|
|
|
@ -44,7 +44,7 @@ public class TreeCutter {
|
|||
return null;
|
||||
|
||||
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
|
||||
while (!frontier.isEmpty()) {
|
||||
|
@ -105,19 +105,24 @@ public class TreeCutter {
|
|||
private static boolean validateCut(IBlockReader reader, BlockPos pos) {
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
List<BlockPos> frontier = new LinkedList<>();
|
||||
frontier.add(pos);
|
||||
frontier.add(pos.up());
|
||||
int posY = pos.getY();
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
BlockPos currentPos = frontier.remove(0);
|
||||
visited.add(currentPos);
|
||||
boolean lowerLayer = currentPos.getY() == posY;
|
||||
|
||||
if (!isLog(reader.getBlockState(currentPos)))
|
||||
continue;
|
||||
if (!pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down())))
|
||||
if (!lowerLayer && !pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down())))
|
||||
return false;
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (direction.getAxis().isVertical())
|
||||
if (direction == Direction.DOWN)
|
||||
continue;
|
||||
if (direction == Direction.UP && !lowerLayer)
|
||||
continue;
|
||||
BlockPos offset = currentPos.offset(direction);
|
||||
if (visited.contains(offset))
|
||||
|
|
|
@ -87,6 +87,11 @@ public class WrappedWorld extends World {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEntity(Entity entityIn) {
|
||||
return world.addEntity(entityIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMapData(MapData mapDataIn) {
|
||||
}
|
||||
|
|
|
@ -35,7 +35,11 @@ import net.minecraft.util.math.Vec3d;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
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.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class MechanicalCrafterBlock extends HorizontalKineticBlock
|
||||
implements IWithTileEntity<MechanicalCrafterTileEntity>, IHaveConnectedTextures {
|
||||
|
@ -149,7 +153,7 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
|
|||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
return super.onWrenched(state, context);
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -170,6 +174,20 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
|
|||
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);
|
||||
if (inSlot.isEmpty())
|
||||
return false;
|
||||
|
|
|
@ -42,7 +42,7 @@ public class DeployerFakePlayer extends FakePlayer {
|
|||
super(world, DEPLOYER_PROFILE);
|
||||
connection = new FakePlayNetHandler(world.getServer(), this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OptionalInt openContainer(INamedContainerProvider container) {
|
||||
return OptionalInt.empty();
|
||||
|
|
|
@ -252,7 +252,7 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
Vec3d rayTarget = center.add(movementVector.scale(5 / 2f - 1 / 64f));
|
||||
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.setPosition(rayOrigin.x, rayOrigin.y, rayOrigin.z);
|
||||
|
||||
|
@ -379,10 +379,6 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
ActionResultType onItemUse = stack.onItemUse(itemusecontext);
|
||||
if (onItemUse == ActionResultType.SUCCESS)
|
||||
return;
|
||||
|
||||
// some items use hard-coded eye positions
|
||||
if (item == Items.SNOWBALL || item == Items.EGG)
|
||||
player.posY -= 1.5f;
|
||||
if (item == Items.ENDER_PEARL)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.elementary;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.Debug;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.simibubi.create.foundation.utility.BlockHelper;
|
|||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -61,6 +62,8 @@ import net.minecraft.world.World;
|
|||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
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.network.PacketDistributor;
|
||||
|
||||
|
@ -253,9 +256,18 @@ public class BlockzapperItem extends Item {
|
|||
world.getBlockState(placed.offset(updateDirection)), world, placed,
|
||||
placed.offset(updateDirection));
|
||||
|
||||
BlockSnapshot blocksnapshot = BlockSnapshot.getBlockSnapshot(world, placed);
|
||||
IFluidState ifluidstate = world.getFluidState(placed);
|
||||
world.setBlockState(placed, ifluidstate.getBlockState(), 18);
|
||||
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()));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,18 @@ import com.simibubi.create.AllItems;
|
|||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
import com.simibubi.create.foundation.utility.TreeCutter;
|
||||
import com.simibubi.create.foundation.utility.TreeCutter.Tree;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.curiosities.tools.AllToolTiers;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.AxeItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
|
@ -40,15 +43,18 @@ public class DeforesterItem extends AxeItem {
|
|||
if (world == null)
|
||||
return;
|
||||
|
||||
Vec3d vec = player.getLookVec();
|
||||
for (BlockPos log : tree.logs)
|
||||
BlockHelper.destroyBlock(world, log, 1 / 2f, item -> {
|
||||
if (dropBlock)
|
||||
Block.spawnAsEntity(world, log, item);
|
||||
if (dropBlock) {
|
||||
dropItemFromCutTree(world, pos, vec, log, item);
|
||||
stack.damageItem(1, player, p -> p.sendBreakAnimation(Hand.MAIN_HAND));
|
||||
}
|
||||
});
|
||||
for (BlockPos leaf : tree.leaves)
|
||||
BlockHelper.destroyBlock(world, leaf, 1 / 8f, item -> {
|
||||
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());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -172,7 +172,8 @@ public class SymmetryWandItem extends Item {
|
|||
Vec3d mirrorPos = symmetry.getPosition();
|
||||
if (mirrorPos.distanceTo(new Vec3d(pos)) > parameters.maxSymmetryWandRange.get())
|
||||
return;
|
||||
if (!player.isCreative() && BlockHelper.findAndRemoveInInventory(block, player, 1) == 0)
|
||||
if (!player.isCreative() && isHoldingBlock(player, block)
|
||||
&& BlockHelper.findAndRemoveInInventory(block, player, 1) == 0)
|
||||
return;
|
||||
|
||||
symmetry.process(blockSet);
|
||||
|
@ -213,6 +214,12 @@ public class SymmetryWandItem extends Item {
|
|||
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) {
|
||||
BlockState air = Blocks.AIR.getDefaultState();
|
||||
BlockState ogBlock = world.getBlockState(pos);
|
||||
|
|
|
@ -23,7 +23,7 @@ public enum AllToolTiers implements IItemTier {
|
|||
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);
|
||||
}),
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ public class TreeFertilizerItem extends Item {
|
|||
if (!world.getBlockState(pos).isNormalCube(world, pos)
|
||||
&& context.getWorld().getBlockState(actualPos).isNormalCube(context.getWorld(), actualPos))
|
||||
continue;
|
||||
if (world.getBlockState(pos).getBlock() == Blocks.PODZOL
|
||||
&& context.getWorld().getBlockState(actualPos).getBlock() != Blocks.GRASS_BLOCK)
|
||||
if (world.getBlockState(pos).getBlock() == Blocks.GRASS_BLOCK
|
||||
|| world.getBlockState(pos).getBlock() == Blocks.PODZOL)
|
||||
continue;
|
||||
|
||||
context.getWorld().setBlockState(actualPos, world.getBlockState(pos));
|
||||
|
@ -80,7 +80,7 @@ public class TreeFertilizerItem extends Item {
|
|||
return Blocks.GRASS_BLOCK.getDefaultState();
|
||||
return super.getBlockState(pos);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue