Did a lot of work on the behaviour of the Inversion Pillar. Also added a Corrupted Zombie for later testing.
This commit is contained in:
parent
d1455920ec
commit
e9549fd9db
10 changed files with 529 additions and 9 deletions
|
@ -1,5 +1,6 @@
|
|||
package WayofTime.bloodmagic.tile;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
|
@ -8,7 +9,10 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.bloodmagic.api.Constants;
|
||||
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
|
||||
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
|
||||
|
@ -25,10 +29,15 @@ public class TileInversionPillar extends TileTicking
|
|||
public static double inversionToIncreaseRadius = 100;
|
||||
public static double inversionToAddPillar = 200;
|
||||
public static double operationThreshold = 20;
|
||||
public static double inversionToSpreadWill = 200;
|
||||
public static double willPushRate = 3;
|
||||
public static double inversionCostPerWillSpread = 4;
|
||||
public static double minimumWillForChunkWhenSpreading = 100;
|
||||
|
||||
public EnumDemonWillType type;
|
||||
public double currentInversion = 0;
|
||||
public int consecutiveFailedChecks = 0; //If you fail enough checks, increase the radius.
|
||||
public int consecutiveFailedAirChecks = 0;
|
||||
public int currentInfectionRadius = 1;
|
||||
|
||||
public int counter = 0;
|
||||
|
@ -76,9 +85,19 @@ public class TileInversionPillar extends TileTicking
|
|||
if (pollute == 1)
|
||||
{
|
||||
consecutiveFailedChecks++;
|
||||
} else if (pollute == 3)
|
||||
{
|
||||
consecutiveFailedAirChecks++;
|
||||
} else if (pollute == 0)
|
||||
{
|
||||
//We successfully found a block to replace!
|
||||
consecutiveFailedChecks = 0;
|
||||
consecutiveFailedAirChecks = 0;
|
||||
}
|
||||
|
||||
if (currentInversion >= inversionToSpreadWill)
|
||||
{
|
||||
spreadWillToSurroundingChunks();
|
||||
}
|
||||
|
||||
if (consecutiveFailedChecks > 5 * currentInfectionRadius && currentInversion >= inversionToIncreaseRadius)
|
||||
|
@ -91,7 +110,97 @@ public class TileInversionPillar extends TileTicking
|
|||
|
||||
if (currentInfectionRadius >= 10 && currentInversion >= inversionToAddPillar)
|
||||
{
|
||||
//TODO: Spawn pillar
|
||||
//TODO: Improve algorithm
|
||||
List<BlockPos> allConnectedPos = InversionPillarHandler.getAllConnectedPillars(worldObj, type, pos);
|
||||
BlockPos candidatePos = findCandidatePositionForPillar(worldObj, type, pos, allConnectedPos, 5, 10);
|
||||
if (!candidatePos.equals(BlockPos.ORIGIN))
|
||||
{
|
||||
currentInversion -= inversionToAddPillar;
|
||||
IBlockState pillarState = ModBlocks.INVERSION_PILLAR.getStateFromMeta(type.ordinal());
|
||||
IBlockState bottomState = ModBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2);
|
||||
IBlockState topState = ModBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2 + 1);
|
||||
worldObj.setBlockState(candidatePos, pillarState);
|
||||
worldObj.setBlockState(candidatePos.down(), bottomState);
|
||||
worldObj.setBlockState(candidatePos.up(), topState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BlockPos findCandidatePositionForPillar(World world, EnumDemonWillType type, BlockPos pos, List<BlockPos> posList, double tooCloseDistance, double wantedAverageDistance)
|
||||
{
|
||||
int maxIterations = 100;
|
||||
int heightCheckRange = 3;
|
||||
|
||||
for (int i = 0; i < maxIterations; i++)
|
||||
{
|
||||
Collections.shuffle(posList);
|
||||
BlockPos pillarPos = posList.get(0);
|
||||
|
||||
Vec3d vec = new Vec3d(world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1).normalize().scale(wantedAverageDistance);
|
||||
|
||||
BlockPos centralPos = pillarPos.add(vec.xCoord, vec.yCoord, vec.zCoord);
|
||||
BlockPos testPos = null;
|
||||
candidateTest: for (int h = 0; h <= heightCheckRange; h++)
|
||||
{
|
||||
for (int sig = -1; sig <= 1; sig += (h > 0 ? 2 : 3))
|
||||
{
|
||||
BlockPos candidatePos = centralPos.add(0, sig * h, 0);
|
||||
IBlockState candidateState = world.getBlockState(candidatePos);
|
||||
if (world.isAirBlock(candidatePos) && world.isAirBlock(candidatePos.up()) && world.isAirBlock(candidatePos.down()) && !world.isAirBlock(candidatePos.down(2)))
|
||||
{
|
||||
testPos = candidatePos;
|
||||
break candidateTest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (testPos != null)
|
||||
{
|
||||
boolean isValid = true;
|
||||
for (BlockPos pillarTestPos : posList)
|
||||
{
|
||||
if (pillarTestPos.distanceSq(testPos) <= tooCloseDistance * tooCloseDistance)
|
||||
{
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid)
|
||||
{
|
||||
return testPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BlockPos.ORIGIN;
|
||||
}
|
||||
|
||||
public void spreadWillToSurroundingChunks()
|
||||
{
|
||||
double currentAmount = WorldDemonWillHandler.getCurrentWill(worldObj, pos, type);
|
||||
if (currentAmount <= minimumWillForChunkWhenSpreading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (EnumFacing side : EnumFacing.HORIZONTALS)
|
||||
{
|
||||
BlockPos offsetPos = pos.offset(side, 16);
|
||||
double sideAmount = WorldDemonWillHandler.getCurrentWill(worldObj, offsetPos, type);
|
||||
if (currentAmount > sideAmount)
|
||||
{
|
||||
double drainAmount = Math.min((currentAmount - sideAmount) / 2, willPushRate);
|
||||
if (drainAmount < willPushRate / 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double drain = WorldDemonWillHandler.drainWill(worldObj, pos, type, drainAmount, true);
|
||||
drain = WorldDemonWillHandler.fillWillToMaximum(worldObj, offsetPos, type, drain, maxWillForChunk, true);
|
||||
|
||||
currentInversion -= drain * inversionCostPerWillSpread;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,14 +285,15 @@ public class TileInversionPillar extends TileTicking
|
|||
* @param currentWillInChunk
|
||||
* @return 0 if the block is successfully placed, 1 if the block is not
|
||||
* placed due to the selected place being invalid, 2 if the block is
|
||||
* not placed due to there not being enough Will or Inversion
|
||||
* not placed due to there not being enough Will or Inversion, 3 if
|
||||
* the block is not placed due to the selected block being air.
|
||||
*/
|
||||
public int polluteNearbyBlocks(double currentWillInChunk)
|
||||
{
|
||||
// System.out.println("Hai! :D Current Inversion: " + currentInversion + ", Current Will: " + currentWillInChunk);
|
||||
if (currentWillInChunk < operationThreshold || currentInversion < inversionPerOperation)
|
||||
{
|
||||
return 2;
|
||||
return 2; //Not enough Will or Inversion available
|
||||
}
|
||||
|
||||
double xOff = worldObj.rand.nextGaussian() * currentInfectionRadius;
|
||||
|
@ -202,7 +312,7 @@ public class TileInversionPillar extends TileTicking
|
|||
BlockPos offsetPos = pos.add(xOff + 0.5, yOff + 0.5, zOff + 0.5);
|
||||
if (offsetPos.equals(pos))
|
||||
{
|
||||
return 1;
|
||||
return 1; //Invalid block (itself!)
|
||||
}
|
||||
|
||||
IBlockState state = worldObj.getBlockState(offsetPos);
|
||||
|
@ -218,13 +328,13 @@ public class TileInversionPillar extends TileTicking
|
|||
WorldDemonWillHandler.drainWill(worldObj, pos, type, willPerOperation, true);
|
||||
currentInversion -= inversionPerOperation;
|
||||
|
||||
return 0;
|
||||
return 0; //Successfully placed
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1; //Invalid block
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 3; //The block was air
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue