Various Updates #143
@@ -7,7 +7,6 @@ import java.util.Queue;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockContainer;
|
|
||||||
import net.minecraft.block.BlockFlowing;
|
import net.minecraft.block.BlockFlowing;
|
||||||
import net.minecraft.block.BlockFluid;
|
import net.minecraft.block.BlockFluid;
|
||||||
import net.minecraft.block.ITileEntityProvider;
|
import net.minecraft.block.ITileEntityProvider;
|
||||||
@@ -27,6 +26,7 @@ import StevenDimDoors.mod_pocketDim.core.DimLink;
|
|||||||
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
import StevenDimDoors.mod_pocketDim.core.NewDimData;
|
||||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||||
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
|
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
|
||||||
|
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||||
import StevenDimDoors.mod_pocketDimClient.ClosingRiftFX;
|
import StevenDimDoors.mod_pocketDimClient.ClosingRiftFX;
|
||||||
import StevenDimDoors.mod_pocketDimClient.GoggleRiftFX;
|
import StevenDimDoors.mod_pocketDimClient.GoggleRiftFX;
|
||||||
import StevenDimDoors.mod_pocketDimClient.RiftFX;
|
import StevenDimDoors.mod_pocketDimClient.RiftFX;
|
||||||
@@ -38,7 +38,7 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||||||
{
|
{
|
||||||
private static final float MIN_IMMUNE_RESISTANCE = 5000.0F;
|
private static final float MIN_IMMUNE_RESISTANCE = 5000.0F;
|
||||||
private static final int BLOCK_DESTRUCTION_RANGE = 4;
|
private static final int BLOCK_DESTRUCTION_RANGE = 4;
|
||||||
private static final int BLOCK_DESTRUCTION_VOLUME = (int) Math.pow(2 * BLOCK_DESTRUCTION_RANGE + 1, 3);
|
private static final int RIFT_SPREAD_RANGE = 5;
|
||||||
private static final int MAX_BLOCK_SEARCH_CHANCE = 100;
|
private static final int MAX_BLOCK_SEARCH_CHANCE = 100;
|
||||||
private static final int BLOCK_SEARCH_CHANCE = 50;
|
private static final int BLOCK_SEARCH_CHANCE = 50;
|
||||||
private static final int MAX_BLOCK_DESTRUCTION_CHANCE = 100;
|
private static final int MAX_BLOCK_DESTRUCTION_CHANCE = 100;
|
||||||
@@ -164,11 +164,30 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||||||
|
|
||||||
private void destroyNearbyBlocks(World world, int x, int y, int z, Random random)
|
private void destroyNearbyBlocks(World world, int x, int y, int z, Random random)
|
||||||
{
|
{
|
||||||
HashMap<Point3D, Integer> pointDistances = new HashMap<Point3D, Integer>(BLOCK_DESTRUCTION_VOLUME);
|
// Find reachable blocks that are vulnerable to rift damage (ignoring air, of course)
|
||||||
Queue<Point3D> points = new LinkedList<Point3D>();
|
ArrayList<Point3D> targets = findReachableBlocks(world, x, y, z, BLOCK_DESTRUCTION_RANGE, false);
|
||||||
|
|
||||||
//Perform a breadth-first search outwards from the point at which the rift is located. Record the distances
|
// For each block, randomly decide whether to destroy it.
|
||||||
//of the points we visit to stop the search at its maximum range.
|
// The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface.
|
||||||
|
for (Point3D target : targets)
|
||||||
|
{
|
||||||
|
if (random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
|
||||||
|
{
|
||||||
|
spawnWorldThread(world.getBlockId(target.getX(), target.getY(), target.getZ()), world, x, y, z, random);
|
||||||
|
world.destroyBlock(target.getX(), target.getY(), target.getZ(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Point3D> findReachableBlocks(World world, int x, int y, int z, int range, boolean includeAir)
|
||||||
|
{
|
||||||
|
int searchVolume = (int) Math.pow(2 * range + 1, 3);
|
||||||
|
HashMap<Point3D, Integer> pointDistances = new HashMap<Point3D, Integer>(searchVolume);
|
||||||
|
Queue<Point3D> points = new LinkedList<Point3D>();
|
||||||
|
ArrayList<Point3D> targets = new ArrayList<Point3D>();
|
||||||
|
|
||||||
|
// Perform a breadth-first search outwards from the point at which the rift is located.
|
||||||
|
// Record the distances of the points we visit to stop the search at its maximum range.
|
||||||
pointDistances.put(new Point3D(x, y, z), 0);
|
pointDistances.put(new Point3D(x, y, z), 0);
|
||||||
addAdjacentBlocks(x, y, z, 0, pointDistances, points);
|
addAdjacentBlocks(x, y, z, 0, pointDistances, points);
|
||||||
while (!points.isEmpty())
|
while (!points.isEmpty())
|
||||||
@@ -176,10 +195,14 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||||||
Point3D current = points.remove();
|
Point3D current = points.remove();
|
||||||
int distance = pointDistances.get(current);
|
int distance = pointDistances.get(current);
|
||||||
|
|
||||||
//If the current block is air, continue searching. Otherwise, try destroying the block.
|
// If the current block is air, continue searching. Otherwise, add the block to our list.
|
||||||
if (world.isAirBlock(current.getX(), current.getY(), current.getZ()))
|
if (world.isAirBlock(current.getX(), current.getY(), current.getZ()))
|
||||||
{
|
{
|
||||||
//Make sure we stay within the search range
|
if (includeAir)
|
||||||
|
{
|
||||||
|
targets.add(current);
|
||||||
|
}
|
||||||
|
// Make sure we stay within the search range
|
||||||
if (distance < BLOCK_DESTRUCTION_RANGE)
|
if (distance < BLOCK_DESTRUCTION_RANGE)
|
||||||
{
|
{
|
||||||
addAdjacentBlocks(current.getX(), current.getY(), current.getZ(), distance, pointDistances, points);
|
addAdjacentBlocks(current.getX(), current.getY(), current.getZ(), distance, pointDistances, points);
|
||||||
@@ -187,16 +210,14 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Check if the current block is immune to destruction by rifts. If not, randomly decide whether to destroy it.
|
// Check if the current block is immune to destruction by rifts. If not, add it to our list.
|
||||||
//The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface.
|
if (!isBlockImmune(world, current.getX(), current.getY(), current.getZ()))
|
||||||
if (!isBlockImmune(world, current.getX(), current.getY(), current.getZ()) &&
|
|
||||||
random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
|
|
||||||
{
|
{
|
||||||
this.spawnWorldThread(world.getBlockId(current.getX(), current.getY(), current.getZ()), world, x, y, z, random);
|
targets.add(current);
|
||||||
world.destroyBlock(current.getX(), current.getY(), current.getZ(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnWorldThread(int blockID, World world, int x, int y, int z, Random random)
|
private void spawnWorldThread(int blockID, World world, int x, int y, int z, Random random)
|
||||||
@@ -236,11 +257,40 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||||||
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4))
|
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4))
|
||||||
{
|
{
|
||||||
int blockID = world.getBlockId(x, y, z);
|
int blockID = world.getBlockId(x, y, z);
|
||||||
world.setBlock(x, y, z, properties.RiftBlockID);
|
if (world.setBlock(x, y, z, properties.RiftBlockID))
|
||||||
this.spawnWorldThread(blockID, world, x, y, z, random);
|
spawnWorldThread(blockID, world, x, y, z, random);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
|
||||||
|
{
|
||||||
|
int x, y, z, blockID;
|
||||||
|
Point4D source = parent.source();
|
||||||
|
|
||||||
|
// Find reachable blocks that are vulnerable to rift damage and include air
|
||||||
|
ArrayList<Point3D> targets = findReachableBlocks(world, source.getX(), source.getY(), source.getZ(),
|
||||||
|
RIFT_SPREAD_RANGE, true);
|
||||||
|
|
||||||
|
if (!targets.isEmpty())
|
||||||
|
{
|
||||||
|
// Choose randomly from among the possible locations where we can spawn a new rift
|
||||||
|
Point3D target = targets.get( random.nextInt(targets.size()) );
|
||||||
|
x = target.getX();
|
||||||
|
y = target.getY();
|
||||||
|
z = target.getZ();
|
||||||
|
|
||||||
|
// Create a child, replace the block with a rift, and consider dropping World Thread
|
||||||
|
blockID = world.getBlockId(x, y, z);
|
||||||
|
if (world.setBlock(x, y, z, properties.RiftBlockID))
|
||||||
|
{
|
||||||
|
dimension.createChildLink(x, y, z, parent);
|
||||||
|
spawnWorldThread(blockID, world, x, y, z, random);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lets pistons push through rifts, destroying them
|
* Lets pistons push through rifts, destroying them
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
|||||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||||
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
|
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public abstract class NewDimData
|
public abstract class NewDimData
|
||||||
{
|
{
|
||||||
private static class InnerDimLink extends DimLink
|
private static class InnerDimLink extends DimLink
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ import StevenDimDoors.mod_pocketDim.util.Point4D;
|
|||||||
|
|
||||||
public class TileEntityRift extends TileEntity
|
public class TileEntityRift extends TileEntity
|
||||||
{
|
{
|
||||||
private static final int MAX_SPREAD_ATTEMPTS = 3;
|
|
||||||
private static final int MAX_SEARCH_ATTEMPTS = 50;
|
|
||||||
private static final int MAX_ANCESTOR_LINKS = 3;
|
private static final int MAX_ANCESTOR_LINKS = 3;
|
||||||
private static final int ENDERMAN_SPAWNING_CHANCE = 1;
|
private static final int ENDERMAN_SPAWNING_CHANCE = 1;
|
||||||
private static final int MAX_ENDERMAN_SPAWNING_CHANCE = 32;
|
private static final int MAX_ENDERMAN_SPAWNING_CHANCE = 32;
|
||||||
@@ -100,7 +98,7 @@ public class TileEntityRift extends TileEntity
|
|||||||
//This code should execute once every 10 seconds
|
//This code should execute once every 10 seconds
|
||||||
if (updateTimer > 200)
|
if (updateTimer > 200)
|
||||||
{
|
{
|
||||||
this.spawnEndermen();
|
//this.spawnEndermen();
|
||||||
this.grow(mod_pocketDim.properties);
|
this.grow(mod_pocketDim.properties);
|
||||||
updateTimer = 0;
|
updateTimer = 0;
|
||||||
}
|
}
|
||||||
@@ -334,53 +332,16 @@ public class TileEntityRift extends TileEntity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The probability of rifts trying to spread increases if more rifts are nearby
|
// The probability of rifts trying to spread increases if more rifts are nearby.
|
||||||
// Players should see rifts spread faster within clusters than at the edges of clusters
|
// Players should see rifts spread faster within clusters than at the edges of clusters.
|
||||||
// Also, single rifts CANNOT spread.
|
// Also, single rifts CANNOT spread.
|
||||||
int nearRifts = dimension.findRiftsInRange(this.worldObj, 5, xCoord, yCoord, zCoord).size();
|
int nearRifts = dimension.findRiftsInRange(worldObj, 5, xCoord, yCoord, zCoord).size();
|
||||||
if (nearRifts == 0 || random.nextInt(nearRifts) == 0)
|
if (nearRifts == 0 || random.nextInt(nearRifts) == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x, y, z;
|
hasGrownRifts = mod_pocketDim.blockRift.spreadRift(dimension, link, worldObj, random);
|
||||||
int spreadAttempts = 0;
|
|
||||||
for (int searchAttempts = 0; searchAttempts < MAX_SEARCH_ATTEMPTS; searchAttempts++)
|
|
||||||
{
|
|
||||||
x = xCoord + MathHelper.getRandomIntegerInRange(random, -6, 6);
|
|
||||||
y = yCoord + MathHelper.getRandomIntegerInRange(random, -4, 4);
|
|
||||||
z = zCoord + MathHelper.getRandomIntegerInRange(random, -6, 6);
|
|
||||||
|
|
||||||
if (y >= 0 && y < worldObj.getActualHeight() && worldObj.isAirBlock(x, y, z))
|
|
||||||
{
|
|
||||||
Vec3 position = worldObj.getWorldVec3Pool().getVecFromPool(xCoord, yCoord, zCoord);
|
|
||||||
Vec3 spreadTarget = worldObj.getWorldVec3Pool().getVecFromPool(x, y, z);
|
|
||||||
MovingObjectPosition hit = worldObj.clip(position, spreadTarget, false);
|
|
||||||
if (hit == null || !mod_pocketDim.blockRift.isBlockImmune(worldObj, hit.blockX, hit.blockY, hit.blockZ))
|
|
||||||
{
|
|
||||||
if(hit!=null)
|
|
||||||
{
|
|
||||||
dimension.createChildLink(hit.blockX, hit.blockY, hit.blockZ, link);
|
|
||||||
this.worldObj.setBlock(hit.blockX, hit.blockY, hit.blockZ, mod_pocketDim.blockRift.blockID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dimension.createChildLink(x,y,z,link);
|
|
||||||
this.worldObj.setBlock(x,y,z, mod_pocketDim.blockRift.blockID);
|
|
||||||
}
|
|
||||||
hasGrownRifts = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spreadAttempts++;
|
|
||||||
if (spreadAttempts >= MAX_SPREAD_ATTEMPTS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user