Skip to content

Commit

Permalink
Changes in bloomery:
Browse files Browse the repository at this point in the history
- Bloomery now stays in place if the four surrounding stone blocks are there.
- Bloomery unlit, reset progress and dump ingredients in world if it's chimney became smaller or the overall structure becomes compromised.
  • Loading branch information
DisasterMoo committed Dec 4, 2019
1 parent 7be9f99 commit 75ea7d0
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 57 deletions.
156 changes: 103 additions & 53 deletions src/main/java/net/dries007/tfc/objects/blocks/devices/BlockBloomery.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.*;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

Expand Down Expand Up @@ -72,59 +69,100 @@ public class BlockBloomery extends BlockHorizontal implements IItemSize, ILighta
}
};

private static final Multiblock BLOOMERY_CHIMNEY, BLOOMERY_BASE, GATE_NORTH, GATE_SOUTH, GATE_EAST, GATE_WEST;
private static final Multiblock BLOOMERY_CHIMNEY; // Helper for determining how high the chimney is
private static final Multiblock[] BLOOMERY_BASE; // If one of those is true, bloomery is formed and can operate (has at least one chimney)
private static final Multiblock GATE_Z, GATE_X; // Determines if the gate can stay in place

static
{
Predicate<IBlockState> stoneMatcher = state -> state.getMaterial() == Material.ROCK && state.isNormalCube();
Predicate<IBlockState> insideChimney = state -> state.getBlock() == BlocksTFC.MOLTEN || state.getMaterial().isReplaceable();
Predicate<IBlockState> center = state -> state.getBlock() == BlocksTFC.CHARCOAL_PILE || state.getBlock() == BlocksTFC.BLOOM || state.getMaterial().isReplaceable();
BLOOMERY_BASE = new Multiblock()

// Bloomery center is the charcoal pile pos
BLOOMERY_BASE = new Multiblock[4];
BLOOMERY_BASE[EnumFacing.NORTH.getHorizontalIndex()] = new Multiblock()
.match(new BlockPos(0, 0, 0), center)
.match(new BlockPos(0, -1, 0), stoneMatcher);
BLOOMERY_CHIMNEY = new Multiblock()
.match(new BlockPos(0, 0, 0), insideChimney)
.match(new BlockPos(1, 0, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher);
//Only one of the gates will return true if the structure is built right
GATE_NORTH = new Multiblock()
.match(new BlockPos(0, 0, 1), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)
.match(new BlockPos(0, -1, 0), stoneMatcher)
.match(new BlockPos(0, 0, 1), state -> state.getBlock() == BlocksTFC.BLOOMERY)
.match(new BlockPos(1, 0, 1), stoneMatcher)
.match(new BlockPos(-1, 0, 1), stoneMatcher)
.match(new BlockPos(0, 1, 1), stoneMatcher)
.match(new BlockPos(0, 1, -1), stoneMatcher)
.match(new BlockPos(1, 1, 0), stoneMatcher)
.match(new BlockPos(-1, 1, 0), stoneMatcher)
.match(new BlockPos(0, -1, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher)
.match(new BlockPos(1, 0, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher);
GATE_SOUTH = new Multiblock()
.match(new BlockPos(0, 0, -1), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)

BLOOMERY_BASE[EnumFacing.SOUTH.getHorizontalIndex()] = new Multiblock()
.match(new BlockPos(0, 0, 0), center)
.match(new BlockPos(0, -1, 0), stoneMatcher)
.match(new BlockPos(0, 0, -1), state -> state.getBlock() == BlocksTFC.BLOOMERY)
.match(new BlockPos(1, 0, -1), stoneMatcher)
.match(new BlockPos(-1, 0, -1), stoneMatcher)
.match(new BlockPos(0, 1, 1), stoneMatcher)
.match(new BlockPos(0, 1, -1), stoneMatcher)
.match(new BlockPos(1, 1, 0), stoneMatcher)
.match(new BlockPos(-1, 1, 0), stoneMatcher)
.match(new BlockPos(0, -1, -1), stoneMatcher)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(1, 0, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher);
GATE_WEST = new Multiblock()
.match(new BlockPos(1, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)

BLOOMERY_BASE[EnumFacing.WEST.getHorizontalIndex()] = new Multiblock()
.match(new BlockPos(0, 0, 0), center)
.match(new BlockPos(0, -1, 0), stoneMatcher)
.match(new BlockPos(1, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY)
.match(new BlockPos(1, 0, -1), stoneMatcher)
.match(new BlockPos(1, 0, 1), stoneMatcher)
.match(new BlockPos(0, 1, 1), stoneMatcher)
.match(new BlockPos(0, 1, -1), stoneMatcher)
.match(new BlockPos(1, 1, 0), stoneMatcher)
.match(new BlockPos(-1, 1, 0), stoneMatcher)
.match(new BlockPos(1, -1, 0), stoneMatcher)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher);
GATE_EAST = new Multiblock()
.match(new BlockPos(-1, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)

BLOOMERY_BASE[EnumFacing.EAST.getHorizontalIndex()] = new Multiblock()
.match(new BlockPos(0, 0, 0), center)
.match(new BlockPos(0, -1, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY)
.match(new BlockPos(-1, 0, -1), stoneMatcher)
.match(new BlockPos(-1, 0, 1), stoneMatcher)
.match(new BlockPos(0, 1, 1), stoneMatcher)
.match(new BlockPos(0, 1, -1), stoneMatcher)
.match(new BlockPos(1, 1, 0), stoneMatcher)
.match(new BlockPos(-1, 1, 0), stoneMatcher)
.match(new BlockPos(-1, -1, 0), stoneMatcher)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher)
.match(new BlockPos(1, 0, 0), stoneMatcher);


BLOOMERY_CHIMNEY = new Multiblock()
.match(new BlockPos(0, 0, 0), insideChimney)
.match(new BlockPos(1, 0, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher);

// Gate center is the bloomery gate block
GATE_Z = new Multiblock()
.match(new BlockPos(0, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)
.match(new BlockPos(1, 0, 0), stoneMatcher)
.match(new BlockPos(-1, 0, 0), stoneMatcher)
.match(new BlockPos(0, 1, 0), stoneMatcher)
.match(new BlockPos(0, -1, 0), stoneMatcher);

GATE_X = new Multiblock()
.match(new BlockPos(0, 0, 0), state -> state.getBlock() == BlocksTFC.BLOOMERY || state.getBlock() == Blocks.AIR)
.match(new BlockPos(0, 0, 1), stoneMatcher)
.match(new BlockPos(0, 0, -1), stoneMatcher)
.match(new BlockPos(0, 1, 0), stoneMatcher)
.match(new BlockPos(0, -1, 0), stoneMatcher);
}

public BlockBloomery()
Expand Down Expand Up @@ -153,22 +191,21 @@ public int getChimneyLevels(World world, BlockPos centerPos)
return 3;
}

public boolean isFormed(World world, BlockPos centerPos, EnumFacing facing)
public boolean canGateStayInPlace(World world, BlockPos pos, EnumFacing.Axis axis)
{
if (!BLOOMERY_BASE.test(world, centerPos)) return false;
if (getChimneyLevels(world, centerPos) == 0) return false;
switch (facing)
if (axis == EnumFacing.Axis.X)
{
case NORTH:
return GATE_NORTH.test(world, centerPos);
case SOUTH:
return GATE_SOUTH.test(world, centerPos);
case EAST:
return GATE_EAST.test(world, centerPos);
case WEST:
return GATE_WEST.test(world, centerPos);
return GATE_X.test(world, pos);
}
else
{
return GATE_Z.test(world, pos);
}
return false;
}

public boolean isFormed(World world, BlockPos centerPos, EnumFacing facing)
{
return BLOOMERY_BASE[facing.getHorizontalIndex()].test(world, centerPos);
}

@Override
Expand Down Expand Up @@ -288,7 +325,7 @@ else if (rayTraceDoor2 == null)
@Override
public boolean canPlaceBlockAt(World worldIn, @Nonnull BlockPos pos)
{
return super.canPlaceBlockAt(worldIn, pos) && getAValidFacing(worldIn, pos) != null;
return super.canPlaceBlockAt(worldIn, pos) && (canGateStayInPlace(worldIn, pos, EnumFacing.Axis.Z) || canGateStayInPlace(worldIn, pos, EnumFacing.Axis.X));
}

@Override
Expand Down Expand Up @@ -324,12 +361,38 @@ public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state,
@Nonnull
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
{
EnumFacing placeDirection = getAValidFacing(worldIn, pos);
if (placeDirection != null)
EnumFacing placeDirection;
float wrappedRotation = MathHelper.wrapDegrees(placer.rotationYaw);
if (canGateStayInPlace(worldIn, pos, EnumFacing.Axis.X))
{
return this.getDefaultState().withProperty(FACING, placeDirection);
// Grab the player facing (in X axis, so, EAST or WEST)
if (wrappedRotation < 0.0F)
{
placeDirection = EnumFacing.EAST;
}
else
{
placeDirection = EnumFacing.WEST;
}
}
else if (canGateStayInPlace(worldIn, pos, EnumFacing.Axis.Z))
{
// Grab the player facing (in Z axis, so, NORTH or SOUTH)
if (wrappedRotation > 90.0F || wrappedRotation < -90.0F)
{
placeDirection = EnumFacing.NORTH;
}
else
{
placeDirection = EnumFacing.SOUTH;
}
}
else
{
// Cannot place, skip
return super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer);
}
return super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer);
return this.getDefaultState().withProperty(FACING, placeDirection);
}

@Override
Expand All @@ -356,17 +419,4 @@ public TileEntity createTileEntity(World world, IBlockState state)
{
return new TEBloomery();
}

@Nullable
private EnumFacing getAValidFacing(World world, BlockPos pos)
{
for (EnumFacing facing : EnumFacing.HORIZONTALS)
{
if (isFormed(world, pos.offset(facing), facing))
{
return facing;
}
}
return null;
}
}
18 changes: 14 additions & 4 deletions src/main/java/net/dries007/tfc/objects/te/TEBloomery.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public void onIgnite()
public void update()
{
if (world.isRemote) return;
IBlockState state = world.getBlockState(pos);
if (--delayTimer <= 0)
{
delayTimer = 20;
Expand All @@ -156,27 +157,37 @@ public void update()
}

int newMaxItems = BlocksTFC.BLOOMERY.getChimneyLevels(world, getInternalBlock()) * 8;
if (!BlocksTFC.BLOOMERY.isFormed(world, getInternalBlock(), world.getBlockState(pos).getValue(FACING)))
if (!BlocksTFC.BLOOMERY.isFormed(world, getInternalBlock(), direction))
{
newMaxItems = 0;
}

maxFuel = newMaxItems;
maxOre = newMaxItems;
boolean turnOff = false;
while (maxOre < oreStacks.size())
{
turnOff = true;
//Structure lost one or more chimney levels
InventoryHelper.spawnItemStack(world, getExternalBlock().getX(), getExternalBlock().getY(), getExternalBlock().getZ(), oreStacks.get(0));
oreStacks.remove(0);
}
while (maxFuel < fuelStacks.size())
{
turnOff = true;
InventoryHelper.spawnItemStack(world, getExternalBlock().getX(), getExternalBlock().getY(), getExternalBlock().getZ(), fuelStacks.get(0));
fuelStacks.remove(0);
}
if (maxOre <= 0)
// Structure became compromised, unlit if needed
if (turnOff && state.getValue(LIT))
{
//Structure became compromised
burnTicksLeft = 0;
state = state.withProperty(LIT, false);
world.setBlockState(pos, state);
}
if (!BlocksTFC.BLOOMERY.canGateStayInPlace(world, pos, direction.getAxis()))
{
// Bloomery gate (the front facing) structure became compromised
world.destroyBlock(pos, true);
return;
}
Expand All @@ -192,7 +203,6 @@ public void update()

updateSlagBlock(this.burnTicksLeft > 0);
}
IBlockState state = world.getBlockState(pos);
if (state.getValue(LIT))
{
if (--burnTicksLeft <= 0)
Expand Down

0 comments on commit 75ea7d0

Please sign in to comment.