Finished BlockRift

This commit is contained in:
zangamj 2016-07-20 11:33:37 -04:00
parent c6bc32483d
commit 863f5644e0
3 changed files with 129 additions and 227 deletions

View file

@ -1,14 +1,9 @@
package com.zixiken.dimdoors.blocks;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.*;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.client.ClosingRiftFX;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.config.DDProperties;
import com.zixiken.dimdoors.core.DimLink;
import com.zixiken.dimdoors.core.PocketManager;
@ -17,14 +12,15 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@ -32,9 +28,9 @@ import net.minecraftforge.fluids.IFluidBlock;
import com.zixiken.dimdoors.core.NewDimData;
import com.zixiken.dimdoors.util.Point4D;
import com.zixiken.dimdoors.client.GoggleRiftFX;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockRift extends Block implements ITileEntityProvider {
private static final float MIN_IMMUNE_RESISTANCE = 5000.0F;
@ -59,41 +55,25 @@ public class BlockRift extends Block implements ITileEntityProvider {
setHardness(1.0F);
setUnlocalizedName(ID);
this.modBlocksImmuneToRift = new ArrayList<Block>();
this.modBlocksImmuneToRift.add(DimDoors.blockDimWall);
this.modBlocksImmuneToRift.add(DimDoors.blockDimWallPerm);
this.modBlocksImmuneToRift.add(DimDoors.dimensionalDoor);
this.modBlocksImmuneToRift.add(DimDoors.warpDoor);
this.modBlocksImmuneToRift.add(DimDoors.transTrapdoor);
this.modBlocksImmuneToRift.add(DimDoors.unstableDoor);
this.modBlocksImmuneToRift.add(DimDoors.blockRift);
this.modBlocksImmuneToRift.add(DimDoors.transientDoor);
this.modBlocksImmuneToRift.add(DimDoors.goldenDimensionalDoor);
this.modBlocksImmuneToRift.add(DimDoors.goldenDoor);
modBlocksImmuneToRift = new ArrayList<Block>();
modBlocksImmuneToRift.add(DimDoors.blockDimWall);
modBlocksImmuneToRift.add(DimDoors.blockDimWallPerm);
modBlocksImmuneToRift.add(DimDoors.dimensionalDoor);
modBlocksImmuneToRift.add(DimDoors.warpDoor);
modBlocksImmuneToRift.add(DimDoors.transTrapdoor);
modBlocksImmuneToRift.add(DimDoors.unstableDoor);
modBlocksImmuneToRift.add(DimDoors.blockRift);
modBlocksImmuneToRift.add(DimDoors.transientDoor);
modBlocksImmuneToRift.add(DimDoors.goldenDimensionalDoor);
modBlocksImmuneToRift.add(DimDoors.goldenDoor);
modBlocksImmuneToRift.add(DimDoors.personalDimDoor);
this.blocksImmuneToRift = new ArrayList<Block>();
this.blocksImmuneToRift.add(DimDoors.blockDimWall);
this.blocksImmuneToRift.add(DimDoors.blockDimWallPerm);
this.blocksImmuneToRift.add(DimDoors.dimensionalDoor);
this.blocksImmuneToRift.add(DimDoors.warpDoor);
this.blocksImmuneToRift.add(DimDoors.transTrapdoor);
this.blocksImmuneToRift.add(DimDoors.unstableDoor);
this.blocksImmuneToRift.add(DimDoors.blockRift);
this.blocksImmuneToRift.add(DimDoors.transientDoor);
this.blocksImmuneToRift.add(DimDoors.goldenDimensionalDoor);
this.blocksImmuneToRift.add(DimDoors.goldenDoor);
this.blocksImmuneToRift.add(DimDoors.personalDimDoor);
this.blocksImmuneToRift.add(Blocks.lapis_block);
this.blocksImmuneToRift.add(Blocks.iron_block);
this.blocksImmuneToRift.add(Blocks.gold_block);
this.blocksImmuneToRift.add(Blocks.diamond_block);
this.blocksImmuneToRift.add(Blocks.emerald_block);
}
@Override
public void registerBlockIcons(IIconRegister par1IconRegister)
{
this.blockIcon = par1IconRegister.registerIcon(DimDoors.modid + ":" + this.getUnlocalizedName());
blocksImmuneToRift = new ArrayList<Block>();
blocksImmuneToRift.add(Blocks.lapis_block);
blocksImmuneToRift.add(Blocks.iron_block);
blocksImmuneToRift.add(Blocks.gold_block);
blocksImmuneToRift.add(Blocks.diamond_block);
blocksImmuneToRift.add(Blocks.emerald_block);
}
@Override
@ -112,9 +92,9 @@ public class BlockRift extends Block implements ITileEntityProvider {
* Returns whether this block is collideable based on the arguments passed in Args: blockMetaData, unknownFlag
*/
@Override
public boolean canCollideCheck(int par1, boolean par2)
public boolean canCollideCheck(IBlockState state, boolean hitIfLiquid)
{
return par2;
return hitIfLiquid;
}
/**
@ -122,75 +102,45 @@ public class BlockRift extends Block implements ITileEntityProvider {
* adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side
*/
@Override
public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
public boolean isBlockSolid(IBlockAccess worldIn, BlockPos pos, EnumFacing side)
{
return true;
}
@Override
public int getRenderType()
{
// This doesn't do anything yet
return 0;
}
/**
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
* coordinates. Args: blockAccess, x, y, z, side
*/
@Override
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
{
return true;
}
/**
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
* cleared to be reused)
*/
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
return null;
}
public int getRenderType() {
return 2; //Tile Entity Special Renderer
}
//function that regulates how many blocks it eats/ how fast it eats them.
@Override
public void updateTick(World world, int x, int y, int z, Random random)
{
if (properties.RiftGriefingEnabled && !world.isRemote &&
PocketManager.getLink(x, y, z, world.provider.dimensionId) != null)
{
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
if (properties.RiftGriefingEnabled && !worldIn.isRemote &&
PocketManager.getLink(pos, worldIn.provider.getDimensionId()) != null) {
//Randomly decide whether to search for blocks to destroy. This reduces the frequency of search operations,
//moderates performance impact, and controls the apparent speed of block destruction.
if (random.nextInt(MAX_BLOCK_SEARCH_CHANCE) < BLOCK_SEARCH_CHANCE &&
((TileEntityRift) world.getTileEntity(x, y, z)).updateNearestRift() )
{
destroyNearbyBlocks(world, x, y, z, random);
if (rand.nextInt(MAX_BLOCK_SEARCH_CHANCE) < BLOCK_SEARCH_CHANCE &&
((TileEntityRift) worldIn.getTileEntity(pos)).updateNearestRift() ) {
destroyNearbyBlocks(worldIn, pos, rand);
}
}
}
private void destroyNearbyBlocks(World world, int x, int y, int z, Random random)
{
private void destroyNearbyBlocks(World world, BlockPos pos, Random random) {
// Find reachable blocks that are vulnerable to rift damage (ignoring air, of course)
ArrayList<BlockPos> targets = findReachableBlocks(world, x, y, z, BLOCK_DESTRUCTION_RANGE, false);
ArrayList<BlockPos> targets = findReachableBlocks(world, pos, BLOCK_DESTRUCTION_RANGE, false);
// For each block, randomly decide whether to destroy it.
// The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface.
for (BlockPos target : targets)
{
if (random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
{
dropWorldThread(world.getBlock(target.getX(), target.getY(), target.getZ()), world, x, y, z, random);
world.func_147480_a(target.getX(), target.getY(), target.getZ(), false);
for (BlockPos target : targets) {
if (random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE) {
dropWorldThread(world, pos, random);
world.destroyBlock(target, false);
}
}
}
private ArrayList<BlockPos> findReachableBlocks(World world, int x, int y, int z, int range, boolean includeAir)
{
private ArrayList<BlockPos> findReachableBlocks(World world, BlockPos pos, int range, boolean includeAir) {
int searchVolume = (int) Math.pow(2 * range + 1, 3);
HashMap<BlockPos, Integer> pointDistances = new HashMap<BlockPos, Integer>(searchVolume);
Queue<BlockPos> points = new LinkedList<BlockPos>();
@ -198,97 +148,73 @@ public class BlockRift extends Block implements ITileEntityProvider {
// 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 BlockPos(x, y, z), 0);
addAdjacentBlocks(x, y, z, 0, pointDistances, points);
while (!points.isEmpty())
{
pointDistances.put(pos, 0);
addAdjacentBlocks(pos, 0, pointDistances, points);
while (!points.isEmpty()) {
BlockPos current = points.remove();
int distance = pointDistances.get(current);
// 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 (includeAir)
{
targets.add(current);
}
if (world.isAirBlock(current)) {
if (includeAir) targets.add(current);
// Make sure we stay within the search range
if (distance < BLOCK_DESTRUCTION_RANGE)
{
addAdjacentBlocks(current.getX(), current.getY(), current.getZ(), distance, pointDistances, points);
}
}
else
{
if (distance < BLOCK_DESTRUCTION_RANGE) addAdjacentBlocks(current, distance, pointDistances, points);
} else {
// Check if the current block is immune to destruction by rifts. If not, add it to our list.
if (!isBlockImmune(world, current.getX(), current.getY(), current.getZ()))
{
targets.add(current);
}
if (!isBlockImmune(world, current)) targets.add(current);
}
}
return targets;
}
public void dropWorldThread(Block block, World world, int x, int y, int z, Random random)
{
if (!block.isAir(world, x, y, z) && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance)
&& !(block instanceof BlockLiquid ||
block instanceof IFluidBlock))
{
public void dropWorldThread(World world, BlockPos pos, Random random) {
Block block = world.getBlockState(pos).getBlock();
if (!block.isAir(world, pos) &&
(random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance) &&
!(block instanceof BlockLiquid || block instanceof IFluidBlock)) {
ItemStack thread = new ItemStack(DimDoors.itemWorldThread, 1);
world.spawnEntityInWorld(new EntityItem(world, x, y, z, thread));
world.spawnEntityInWorld(new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), thread));
}
}
private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<BlockPos, Integer> pointDistances, Queue<BlockPos> points)
{
BlockPos[] neighbors = new BlockPos[] {
new BlockPos(x - 1, y, z),
new BlockPos(x + 1, y, z),
new BlockPos(x, y - 1, z),
new BlockPos(x, y + 1, z),
new BlockPos(x, y, z - 1),
new BlockPos(x, y, z + 1)
private static void addAdjacentBlocks(BlockPos pos, int distance, HashMap<BlockPos, Integer> pointDistances, Queue<BlockPos> points) {
BlockPos[] neighbors = {
pos.north(),
pos.south(),
pos.up(),
pos.down(),
pos.west(),
pos.east()
};
for (int index = 0; index < neighbors.length; index++)
{
if (!pointDistances.containsKey(neighbors[index]))
{
pointDistances.put(neighbors[index], distance + 1);
points.add(neighbors[index]);
for (BlockPos neighbor : neighbors) {
if (!pointDistances.containsKey(neighbor)) {
pointDistances.put(neighbor, distance + 1);
points.add(neighbor);
}
}
}
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
{
int x, y, z;
Block block = null;
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random) {
Point4D source = parent.source();
// Find reachable blocks that are vulnerable to rift damage and include air
ArrayList<BlockPos> targets = findReachableBlocks(world, source.getX(), source.getY(), source.getZ(),
RIFT_SPREAD_RANGE, true);
ArrayList<BlockPos> targets = findReachableBlocks(world, source.toBlockPos(), RIFT_SPREAD_RANGE, true);
if (!targets.isEmpty())
{
if (!targets.isEmpty()) {
// Choose randomly from among the possible locations where we can spawn a new rift
BlockPos 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
block = world.getBlock(x, y, z);
if (world.setBlock(x, y, z, DimDoors.blockRift))
{
dimension.createChildLink(x, y, z, parent);
dropWorldThread(block, world, x, y, z, random);
if (world.setBlockState(target, getDefaultState())) {
dimension.createChildLink(target, parent);
dropWorldThread(world, target, random);
return true;
}
}
return false;
return false;
}
/**
@ -301,102 +227,78 @@ public class BlockRift extends Block implements ITileEntityProvider {
}
/**
* regulates the render effect, especially when multiple rifts start to link up. Has 3 main parts- Grows toward and away from nearest rft, bends toward it, and a randomization function
* regulates the render effect, especially when multiple rifts start to link up.
* Has 3 main parts- Grows toward and away from nearest rift, bends toward it, and a randomization function
*/
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World world, int x, int y, int z, Random rand)
{
public void randomDisplayTick(World worldIn, BlockPos pos, IBlockState state, Random rand) {
//ArrayList<BlockPos> targets = findReachableBlocks(worldIn, pos, 2, false);
//TODO: implement the parts specified in the method comment?
int x = pos.getX(), y = pos.getY(), z = pos.getZ();
ArrayList<BlockPos> targets=findReachableBlocks(world, x, y, z, 2, false);
TileEntityRift tile = (TileEntityRift)world.getTileEntity(x, y, z);
//renders an extra little blob on top of the actual rift location so its easier to find. Eventually will only render if the player has the goggles.
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
TileEntityRift tile = (TileEntityRift)worldIn.getTileEntity(pos);
//renders an extra little blob on top of the actual rift location so its easier to find.
// Eventually will only render if the player has the goggles.
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(
worldIn,
x+.5, y+.5, z+.5,
rand.nextGaussian()*0.01D, rand.nextGaussian()*0.01D, rand.nextGaussian()*0.01D,
FMLClientHandler.instance().getClient().effectRenderer));
if(tile.shouldClose)
{
//renders an opposite color effect if it is being closed by the rift remover
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
}
//renders an opposite color effect if it is being closed by the rift remover
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(
worldIn,
x+.5, y+.5, z+.5,
rand.nextGaussian()*0.01D, rand.nextGaussian()*0.01D, rand.nextGaussian()*0.01D,
FMLClientHandler.instance().getClient().effectRenderer));
}
public boolean tryPlacingRift(World world, int x, int y, int z)
{
if (world != null && !isBlockImmune(world, x, y, z))
{
return world.setBlock(x, y, z, DimDoors.blockRift);
}
return false;
public boolean tryPlacingRift(World world, BlockPos pos) {
return world != null && !isBlockImmune(world, pos) && world.setBlockState(pos, getDefaultState());
}
public boolean isBlockImmune(World world, int x, int y, int z)
{
Block block = world.getBlock(x, y, z);
if (block != null)
{
// SenseiKiwi: I've switched to using the block's blast resistance instead of its
// hardness since most defensive blocks are meant to defend against explosions and
// may have low hardness to make them easier to build with. However, block.getExplosionResistance()
// is designed to receive an entity, the source of the blast. We have no entity so
// I've set this to access blockResistance directly. Might need changing later.
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block) ||
blocksImmuneToRift.contains(block));
}
return false;
public boolean isBlockImmune(World world, BlockPos pos) {
Block block = world.getBlockState(pos).getBlock();
// SenseiKiwi: I've switched to using the block's blast resistance instead of its
// hardness since most defensive blocks are meant to defend against explosions and
// may have low hardness to make them easier to build with. However, block.getExplosionResistance()
// is designed to receive an entity, the source of the blast. We have no entity so
// I've set this to access blockResistance directly. Might need changing later.
return block != null &&
(block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block) ||
blocksImmuneToRift.contains(block));
}
public boolean isModBlockImmune(World world, int x, int y, int z)
{
public boolean isModBlockImmune(World world, BlockPos pos) {
// Check whether the block at the specified location is one of the
// rift-resistant blocks from DD.
Block block = world.getBlock(x, y, z);
if (block != null)
{
return modBlocksImmuneToRift.contains(block);
}
return false;
Block block = world.getBlockState(pos).getBlock();
return block != null && modBlocksImmuneToRift.contains(block);
}
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player)
{
public ItemStack getPickBlock(MovingObjectPosition target, World world, BlockPos pos, EntityPlayer player) {
return null;
}
@Override
public Item getItemDropped(int par1, Random par2Random, int par3)
{
return null;
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune) {return null;}
@Override
@Override
public TileEntity createNewTileEntity(World world, int metadata)
{
return new TileEntityRift();
}
@Override
public void breakBlock(World world, int x, int y, int z, Block oldBlock, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlock, oldMeta);
public void breakBlock(World world, BlockPos pos, IBlockState state) {
world.removeTileEntity(pos);
// Schedule rift regeneration for this block if it was changed
if (world.getBlock(x, y, z) != oldBlock)
{
DimDoors.riftRegenerator.scheduleSlowRegeneration(x, y, z, world);
}
if (world.getBlockState(pos).getBlock() != state.getBlock())
DimDoors.riftRegenerator.scheduleSlowRegeneration(pos, world);
}
}

View file

@ -2,15 +2,15 @@ package com.zixiken.dimdoors.client;
import com.zixiken.dimdoors.core.PocketManager;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.particle.EntityFireworkSparkFX;
import net.minecraft.client.particle.EntityFirework;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GoggleRiftFX extends EntityFireworkSparkFX
public class GoggleRiftFX extends EntityFirework.SparkFX
{
private int field_92049_a = 160;
private boolean field_92054_ax;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB