Fixed NPE in yCoordHelper, Other Bugs, Reimplemented Limbo Decay #52

Merged
SenseiKiwi merged 8 commits from 1.4.1fixes into master 2013-07-26 19:32:37 +00:00
7 changed files with 367 additions and 390 deletions

View File

@@ -4,14 +4,11 @@ import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Random; import java.util.Random;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper; import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper; import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
import StevenDimDoors.mod_pocketDim.ticking.MobObelisk; import StevenDimDoors.mod_pocketDim.ticking.MobObelisk;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.TickType;
@@ -19,15 +16,18 @@ import cpw.mods.fml.relauncher.Side;
public class CommonTickHandler implements ITickHandler public class CommonTickHandler implements ITickHandler
{ {
private Random rand = new Random(); private int tickCount = 0;
public int tickCount=0;
public int tickCount2=0;
private static DDProperties properties = null; private static DDProperties properties = null;
public static ArrayList<int[]> chunksToPopulate= new ArrayList<int[]>(); public static ArrayList<int[]> chunksToPopulate = new ArrayList<int[]>();
private static final Random rand = new Random();
public static final int MAX_MONOLITH_SPAWNING_CHANCE = 100; public static final int MAX_MONOLITH_SPAWNING_CHANCE = 100;
private static final String label = "Dimensional Doors: Common Tick";
private static final int MAX_MONOLITH_SPAWN_Y = 245; private static final int MAX_MONOLITH_SPAWN_Y = 245;
private static final int CHUNK_SIZE = 16; private static final int CHUNK_SIZE = 16;
private static final int RIFT_REGENERATION_INTERVAL = 100; //Regenerate random rifts every 100 ticks
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks
public CommonTickHandler() public CommonTickHandler()
{ {
@@ -40,7 +40,7 @@ public class CommonTickHandler implements ITickHandler
{ {
if (type.equals(EnumSet.of(TickType.SERVER))) if (type.equals(EnumSet.of(TickType.SERVER)))
{ {
onTickInGame(); onServerTick();
} }
} }
@@ -51,9 +51,12 @@ public class CommonTickHandler implements ITickHandler
{ {
if(!CommonTickHandler.chunksToPopulate.isEmpty()) if(!CommonTickHandler.chunksToPopulate.isEmpty())
{ {
for(int[] chunkData : CommonTickHandler.chunksToPopulate) //TODO: This is bad. =/ We should not be passing around arrays of magic numbers.
//We should have an object that contains this information. ~SenseiKiwi
for (int[] chunkData : CommonTickHandler.chunksToPopulate)
{ {
if(chunkData[0]==properties.LimboDimensionID) if(chunkData[0] == properties.LimboDimensionID)
{ {
this.placeMonolithsInLimbo(chunkData[0], chunkData[1], chunkData[2]); this.placeMonolithsInLimbo(chunkData[0], chunkData[1], chunkData[2]);
} }
@@ -68,14 +71,16 @@ public class CommonTickHandler implements ITickHandler
} }
} }
public EnumSet ticks() @Override
public EnumSet<TickType> ticks()
{ {
return EnumSet.of(TickType.SERVER); return EnumSet.of(TickType.SERVER);
} }
@Override
public String getLabel() public String getLabel()
{ {
return null; return label; //Used for profiling!
} }
private void placeMonolithsInPockets(int worldID, int chunkX, int chunkZ) private void placeMonolithsInPockets(int worldID, int chunkX, int chunkZ)
@@ -98,7 +103,7 @@ public class CommonTickHandler implements ITickHandler
Random random = new Random(worldObj.getSeed()); Random random = new Random(worldObj.getSeed());
long factorA = random.nextLong() / 2L * 2L + 1L; long factorA = random.nextLong() / 2L * 2L + 1L;
long factorB = random.nextLong() / 2L * 2L + 1L; long factorB = random.nextLong() / 2L * 2L + 1L;
random.setSeed((long)chunkX * factorA + (long)chunkZ * factorB ^ worldObj.getSeed()); random.setSeed(chunkX * factorA + chunkZ * factorB ^ worldObj.getSeed());
int x, y, z; int x, y, z;
do do
@@ -206,20 +211,36 @@ public class CommonTickHandler implements ITickHandler
while (yTest > y); while (yTest > y);
} }
} }
//replaces rifts in game that have been destroyed/have blocks placed over them.
private void onTickInGame()
{
private void onServerTick()
{
tickCount++; //There is no need to reset the counter. Let it overflow. Really.
if (tickCount % RIFT_REGENERATION_INTERVAL == 0)
{
regenerateRifts();
}
if (tickCount % LIMBO_DECAY_INTERVAL == 0)
{
LimboDecay.ApplyRandomFastDecay();
}
if (mod_pocketDim.teleTimer > 0)
{
mod_pocketDim.teleTimer--;
}
}
private void regenerateRifts()
{
try try
{ {
//Regenerate rifts that have been replaced (not permanently removed) by players
if(tickCount>100) int i = 0;
{
tickCount=0;
int i=0;
while (i < 15 && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER)
while (i<15&&FMLCommonHandler.instance().getEffectiveSide()==Side.SERVER)
{ {
i++; i++;
LinkData link; LinkData link;
@@ -227,23 +248,18 @@ public class CommonTickHandler implements ITickHandler
//actually gets the random rift based on the size of the list //actually gets the random rift based on the size of the list
link = (LinkData) dimHelper.instance.getRandomLinkData(true); link = (LinkData) dimHelper.instance.getRandomLinkData(true);
if(link!=null) if(link!=null)
{ {
if(dimHelper.getWorld(link.locDimID)!=null) if (dimHelper.getWorld(link.locDimID)!=null)
{ {
World world=dimHelper.getWorld(link.locDimID); World world = dimHelper.getWorld(link.locDimID);
int blocktoReplace = world.getBlockId(link.locXCoord, link.locYCoord, link.locZCoord); int blocktoReplace = world.getBlockId(link.locXCoord, link.locYCoord, link.locZCoord);
if(!mod_pocketDim.blocksImmuneToRift.contains(blocktoReplace))//makes sure the rift doesn't replace a door or something if(!mod_pocketDim.blocksImmuneToRift.contains(blocktoReplace))//makes sure the rift doesn't replace a door or something
{ {
if(dimHelper.instance.getLinkDataFromCoords(link.locXCoord, link.locYCoord, link.locZCoord, link.locDimID)==null) if(dimHelper.instance.getLinkDataFromCoords(link.locXCoord, link.locYCoord, link.locZCoord, link.locDimID) != null)
{
}
else
{ {
dimHelper.getWorld(link.locDimID).setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID); dimHelper.getWorld(link.locDimID).setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID);
TileEntityRift.class.cast(dimHelper.getWorld(link.locDimID).getBlockTileEntity(link.locXCoord, link.locYCoord, link.locZCoord)).hasGrownRifts=true; TileEntityRift.class.cast(dimHelper.getWorld(link.locDimID).getBlockTileEntity(link.locXCoord, link.locYCoord, link.locZCoord)).hasGrownRifts=true;
@@ -253,92 +269,10 @@ public class CommonTickHandler implements ITickHandler
} }
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
tickCount++; System.out.println("An exception occurred in CommonTickHandler.onServerTick():");
System.out.println("something on tick went wrong: " + e);
e.printStackTrace(); e.printStackTrace();
} }
tickCount++;
//this section regulates decay in Limbo- it records any blocks placed by the player and later progresss them through the decay cycle
if(tickCount2>10&&dimHelper.blocksToDecay!=null)
{
tickCount2=0;
if(!dimHelper.blocksToDecay.isEmpty()&&dimHelper.getWorld(properties.LimboDimensionID)!=null)
{
if(dimHelper.blocksToDecay.size()>rand.nextInt(400))
{
int index = rand.nextInt(dimHelper.blocksToDecay.size());
Point3D point = (Point3D) dimHelper.blocksToDecay.get(index);
int blockID = dimHelper.getWorld(properties.LimboDimensionID).getBlockId(point.getX(), point.getY(), point.getZ());
int idToSet=Block.stone.blockID;
if(blockID==0||blockID==properties.LimboBlockID)
{
dimHelper.blocksToDecay.remove(index);
} }
else
{
if(Block.blocksList[idToSet] instanceof BlockContainer)
{
idToSet=-1;
dimHelper.blocksToDecay.remove(index);
}
if(blockID==Block.cobblestone.blockID)
{
idToSet=Block.gravel.blockID;
}
if(blockID==Block.stone.blockID)
{
idToSet=Block.cobblestone.blockID;
}
if(blockID==Block.gravel.blockID&&!dimHelper.getWorld(properties.LimboDimensionID).isAirBlock(point.getX(), point.getY()-1, point.getZ()))
{
idToSet=properties.LimboBlockID;
dimHelper.getWorld(properties.LimboDimensionID).scheduleBlockUpdate(point.getX(), point.getY(), point.getZ(),10, idToSet);
}
else if(blockID==Block.gravel.blockID)
{
dimHelper.blocksToDecay.remove(index);
idToSet=-1;
}
if(idToSet!=-1)
{
dimHelper.getWorld(properties.LimboDimensionID).setBlock(point.getX(), point.getY(), point.getZ(), idToSet);
}
}
}
}
}
tickCount2++;
if(mod_pocketDim.teleTimer>0)
{
mod_pocketDim.teleTimer--;
}
}
} }

View File

@@ -1,50 +1,17 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
import StevenDimDoors.mod_pocketDim.items.ItemRiftBlade;
import StevenDimDoors.mod_pocketDim.world.LimboGenerator;
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PocketGenerator;
import StevenDimDoors.mod_pocketDim.world.pocketProvider;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.client.event.sound.SoundLoadEvent; import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.event.Event.Result;
import net.minecraftforge.event.ForgeSubscribe; import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerDropsEvent; import net.minecraftforge.event.entity.player.PlayerDropsEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class EventHookContainer public class EventHookContainer
{ {
private static Random rand = new Random();
private static DDProperties properties = null; private static DDProperties properties = null;
public EventHookContainer() public EventHookContainer()
@@ -57,8 +24,6 @@ public class EventHookContainer
@ForgeSubscribe @ForgeSubscribe
public void onSoundLoad(SoundLoadEvent event) public void onSoundLoad(SoundLoadEvent event)
{ {
File dataDir = Minecraft.getMinecraft().mcDataDir;
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/monk.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/monk.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/monk.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/monk.ogg")));
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/crack.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/crack.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/crack.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/crack.ogg")));
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/tearing.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/tearing.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/tearing.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/tearing.ogg")));
@@ -67,40 +32,39 @@ public class EventHookContainer
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftEnd.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftEnd.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftEnd.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftEnd.ogg")));
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftClose.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftClose.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftClose.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftClose.ogg")));
event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftDoor.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftDoor.ogg"))); event.manager.soundPoolSounds.addSound("mods/DimDoors/sfx/riftDoor.ogg", (mod_pocketDim.class.getResource("/mods/DimDoors/sfx/riftDoor.ogg")));
} }
@ForgeSubscribe @ForgeSubscribe
public void onWorldLoad(WorldEvent.Load event) public void onWorldLoad(WorldEvent.Load event)
{ {
if(!mod_pocketDim.hasInitDims&&event.world.provider.dimensionId==0&&!event.world.isRemote) if (!mod_pocketDim.hasInitDims && event.world.provider.dimensionId == 0 && !event.world.isRemote)
{ {
System.out.println("Registering Pocket Dims"); System.out.println("Registering Pocket Dims");
mod_pocketDim.hasInitDims=true; mod_pocketDim.hasInitDims = true;
dimHelper.instance.unregsisterDims(); dimHelper.instance.unregsisterDims();
dimHelper.dimList.clear(); dimHelper.dimList.clear();
dimHelper.instance.interDimLinkList.clear(); dimHelper.instance.interDimLinkList.clear();
dimHelper.instance.initPockets(); dimHelper.instance.initPockets();
} }
for(Integer ids : dimHelper.getIDs()) for (Integer ids : dimHelper.getIDs())
{ {
World world = dimHelper.getWorld(ids); World world = dimHelper.getWorld(ids);
int linkCount=0; int linkCount = 0;
if(dimHelper.dimList.containsKey(world.provider.dimensionId)) if (dimHelper.dimList.containsKey(world.provider.dimensionId))
{ {
//TODO added temporary Try/catch block to prevent a crash here, getLinksInDim needs to be looked at //TODO added temporary Try/catch block to prevent a crash here, getLinksInDim needs to be looked at
try try
{ {
for(LinkData link:dimHelper.dimList.get(world.provider.dimensionId).getLinksInDim()) for (LinkData link:dimHelper.dimList.get(world.provider.dimensionId).getLinksInDim())
{ {
if(linkCount>100) if(linkCount>100) //TODO: Wtf? wouldn't this cause some links to not load on servers with several links? Not sure what's going on here. ~SenseiKiwi
{ {
break; break;
} }
linkCount++; linkCount++;
int blocktoReplace = world.getBlockId(link.locXCoord, link.locYCoord, link.locZCoord); int blocktoReplace = world.getBlockId(link.locXCoord, link.locYCoord, link.locZCoord);
if(!mod_pocketDim.blocksImmuneToRift.contains(blocktoReplace)) if (!mod_pocketDim.blocksImmuneToRift.contains(blocktoReplace))
{ {
dimHelper.getWorld(link.locDimID).setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID); dimHelper.getWorld(link.locDimID).setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID);
} }
@@ -114,65 +78,24 @@ public class EventHookContainer
} }
} }
@ForgeSubscribe
public void EntityJoinWorldEvent(net.minecraftforge.event.entity.EntityJoinWorldEvent event)
{
if(event.entity instanceof EntityPlayer)
{
// System.out.println(event.entity.worldObj.provider.dimensionId);
// PacketDispatcher.sendPacketToPlayer(DimUpdatePacket.sendPacket(event.world.provider.dimensionId,1),(Player) event.entity);
}
}
@ForgeSubscribe @ForgeSubscribe
public void onPlayerFall(LivingFallEvent event) public void onPlayerFall(LivingFallEvent event)
{ {
event.setCanceled(event.entity.worldObj.provider.dimensionId==properties.LimboDimensionID); event.setCanceled(event.entity.worldObj.provider.dimensionId == properties.LimboDimensionID);
} }
@ForgeSubscribe
public void onPlayerInteract(PlayerInteractEvent event)
{
if(event.entityPlayer.worldObj.provider.dimensionId==properties.LimboDimensionID&&event.action==PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK)
{
int x = event.x;
int y = event.y;
int z = event.z;
if(event.entityPlayer.getHeldItem()!=null)
{
if(event.entityPlayer.getHeldItem().getItem() instanceof ItemBlock)
{
if(event.entityPlayer instanceof EntityPlayerMP)
{
Point3D point = new Point3D(x,y,z);
dimHelper.blocksToDecay.add(point);
}
}
}
}
}
@ForgeSubscribe @ForgeSubscribe
public void onPlayerDrops(PlayerDropsEvent event) public void onPlayerDrops(PlayerDropsEvent event)
{ {
//TODO: I have some doubts. Is this triggered even if you die outside Limbo? And do you still drop items that others could pick up? We don't cancel the event. ~SenseiKiwi
mod_pocketDim.limboSpawnInventory.put(event.entityPlayer.username, event.drops); mod_pocketDim.limboSpawnInventory.put(event.entityPlayer.username, event.drops);
} }
@ForgeSubscribe
public void onWorldunload(WorldEvent.Unload event)
{
}
@ForgeSubscribe @ForgeSubscribe
public void onWorldsave(WorldEvent.Save event) public void onWorldsave(WorldEvent.Save event)
{ {
if(mod_pocketDim.hasInitDims&&event.world.provider.dimensionId==0) if (mod_pocketDim.hasInitDims && event.world.provider.dimensionId == 0)
{ {
dimHelper.instance.save(); dimHelper.instance.save();
} }

View File

@@ -0,0 +1,170 @@
package StevenDimDoors.mod_pocketDim;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
/**
* Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo
* naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes.
*/
public class LimboDecay {
private static final int MAX_DECAY_SPREAD_CHANCE = 100;
private static final int DECAY_SPREAD_CHANCE = 50;
private static final int CHUNK_SIZE = 16;
private static final int SECTION_HEIGHT = 16;
//Provides a reversed list of the block IDs that blocks cycle through during decay.
//Must be initialized later since it requires DDProperties to be initialized (for LimboBlockID).
private static int[] decaySequence = null;
private static Random random = new Random();
private static DDProperties properties = null;
private LimboDecay() { }
/**
* Initializes the array containing the reversed sequence of block IDs that blocks cycle through during decay.
*/
private static void InitializeDecaySequence()
{
if (decaySequence == null)
{
if (properties == null)
properties = DDProperties.instance();
decaySequence = new int[] {
properties.LimboBlockID,
Block.gravel.blockID,
Block.cobblestone.blockID,
Block.stone.blockID
};
}
}
/**
* Checks the blocks orthogonally around a given location (presumably the location of an Unraveled Fabric block)
* and applies Limbo decay to them. This gives the impression that decay spreads outward from Unraveled Fabric.
*/
public static void ApplySpreadDecay(World world, int x, int y, int z)
{
if (properties == null)
properties = DDProperties.instance();
//Check if we randomly apply decay spread or not. This can be used to moderate the frequency of
//full spread decay checks, which can also shift its performance impact on the game.
if (random.nextInt(MAX_DECAY_SPREAD_CHANCE) < DECAY_SPREAD_CHANCE)
{
//Apply decay to the blocks above, below, and on all four sides.
//World.getBlockId() implements bounds checking, so we don't have to worry about reaching out of the world
DecayBlock(world, x - 1, y, z);
DecayBlock(world, x + 1, y, z);
DecayBlock(world, x, y, z - 1);
DecayBlock(world, x, y, z + 1);
DecayBlock(world, x, y - 1, z);
DecayBlock(world, x, y + 1, z);
}
}
/**
* Picks random blocks from each active chunk in Limbo and, if decay is applicable, converts them directly to Unraveled Fabric.
* This decay method is designed to stop players from avoiding Limbo decay by building floating structures.
*/
public static void ApplyRandomFastDecay()
{
if (properties == null)
properties = DDProperties.instance();
int x, y, z;
int sectionY;
int limboHeight;
World limbo = dimHelper.getWorld(properties.LimboDimensionID);
if (limbo != null)
{
limboHeight = limbo.getHeight();
//Obtain the coordinates of active chunks in Limbo. For each section of each chunk,
//pick a random block and try to apply fast decay.
for (Object coordObject : limbo.activeChunkSet)
{
ChunkCoordIntPair chunkCoord = (ChunkCoordIntPair) coordObject;
//Loop through each chunk section and fast-decay a random block
//Apply the changes using the world object instead of directly to the chunk so that clients are always notified.
for (sectionY = 0; sectionY < limboHeight; sectionY += SECTION_HEIGHT)
{
x = chunkCoord.chunkXPos * CHUNK_SIZE + random.nextInt(CHUNK_SIZE);
z = chunkCoord.chunkZPos * CHUNK_SIZE + random.nextInt(CHUNK_SIZE);
y = sectionY + random.nextInt(SECTION_HEIGHT);
DecayBlockFast(limbo, x, y, z);
}
}
}
}
/**
* Checks if a block can be decayed and, if so, changes it directly into Unraveled Fabric.
*/
private static boolean DecayBlockFast(World world, int x, int y, int z)
{
int blockID = world.getBlockId(x, y, z);
if (CanDecayBlock(blockID))
{
world.setBlock(x, y, z, properties.LimboBlockID);
return true;
}
return false;
}
/**
* Checks if a block can be decayed and, if so, changes it to the next block ID along the decay sequence.
*/
private static boolean DecayBlock(World world, int x, int y, int z)
{
//Make sure the decay sequence is initialized
InitializeDecaySequence();
int index;
int blockID = world.getBlockId(x, y, z);
if (CanDecayBlock(blockID))
{
//Loop over the block IDs that decay can go through.
//Find an index matching the current blockID, if any.
for (index = 0; index < decaySequence.length; index++)
{
if (decaySequence[index] == blockID)
{
break;
}
}
//Since the decay sequence is a reversed list, the block ID in the index before our match
//is the block ID we should change this block into. A trick in this approach is that if
//we loop over the array without finding a match, then (index - 1) will contain the
//last ID in the array, which is the first one that all blocks decay into.
//We assume that Unraveled Fabric is NOT decayable. Otherwise, this will go out of bounds!
world.setBlock(x, y, z, decaySequence[index - 1]);
return true;
}
return false;
}
/**
* Checks if a block can decay. We will not decay air, Unraveled Fabric, Eternal Fabric, or containers.
*/
private static boolean CanDecayBlock(int blockID)
{
if (blockID == 0 || blockID == properties.LimboBlockID || blockID == properties.PermaFabricBlockID)
return false;
Block block = Block.blocksList[blockID];
return (block == null || !(block instanceof BlockContainer));
}
}

View File

@@ -5,113 +5,58 @@ import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.LimboDecay;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
public class BlockLimbo extends Block public class BlockLimbo extends Block
{ {
Random rand= new Random(); private final int limboDimensionID;
Icon blockIcon0;
Icon blockIcon1;
Icon blockIcon2;
Icon blockIcon3;
public BlockLimbo(int i, int j, Material par2Material) public BlockLimbo(int i, int j, Material par2Material, int limboDimensionID)
{ {
super(i, Material.ground); super(i, Material.ground);
setTickRandomly(false); this.limboDimensionID = limboDimensionID;
this.setTickRandomly(true);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab); this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
} }
@SideOnly(Side.CLIENT)
/** /**
* Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side
*/ */
public Icon getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) @SideOnly(Side.CLIENT)
@Override
public Icon getBlockTexture(IBlockAccess blockAccess, int x, int y, int z, int side)
{ {
return this.getIcon(par5, par1IBlockAccess.getBlockMetadata(par2, par3, par4)); return this.getIcon(side, blockAccess.getBlockMetadata(x, y, z));
}
public void registerIcons(IconRegister par1IconRegister)
{
this.blockIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2());
this.blockIcon0 = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2()+0);
this.blockIcon1 = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2()+1);
this.blockIcon2 = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2()+2);
this.blockIcon3 = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2()+3);
} }
@Override
public void registerIcons(IconRegister iconRegister)
{
this.blockIcon = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName2());
}
@Override
public Icon getIcon(int par1, int par2) public Icon getIcon(int par1, int par2)
{ {
/**
switch(par2)
{
case 0: return this.blockIcon0;
case 1: return this.blockIcon1;
case 2: return this.blockIcon2;
case 3: return this.blockIcon3;
}
**/
return this.blockIcon; return this.blockIcon;
} }
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {} /**
* If the block is in Limbo, attempt to decay surrounding blocks upon receiving a random update tick.
//part of the decay mech, if a block has fallen onto it, when it turns, it makes sure any block above it gets added too. */
@Override @Override
public void updateTick(World world, int x, int y, int z, Random random)
public int quantityDropped(Random par1Random)
{ {
//Make sure this block is in Limbo
if (world.provider.dimensionId == limboDimensionID)
return 1;
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9)
{ {
LimboDecay.ApplySpreadDecay(world, x, y, z);
return false;
}
//if a block lands on it and its gravel, adds it to the decay list
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
{
if(par1World.getBlockId(par2, par3+1, par4)==Block.gravel.blockID)
{
Point3D point = new Point3D(par2,par3+1,par4);
dimHelper.blocksToDecay.add(point);
}
}
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
if(par1World.getBlockId(par2, par3+1, par4)==Block.gravel.blockID)
{
Point3D point = new Point3D(par2,par3+1,par4);
dimHelper.blocksToDecay.add(point);
} }
} }
@Override
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
// par1World.setBlockMetadataWithNotify(par2, par3, par4, this.rand.nextInt(4), 0);
}
//TODO set render color!!
} }

View File

@@ -409,7 +409,7 @@ public class DungeonHelper
xEnd = centerX + MAX_EXPORT_RADIUS; xEnd = centerX + MAX_EXPORT_RADIUS;
zEnd = centerZ + MAX_EXPORT_RADIUS; zEnd = centerZ + MAX_EXPORT_RADIUS;
yEnd = Math.min(centerY + MAX_EXPORT_RADIUS, world.getActualHeight()); yEnd = Math.min(centerY + MAX_EXPORT_RADIUS, world.getHeight());
//This could be done more efficiently, but honestly, this is the simplest approach and it //This could be done more efficiently, but honestly, this is the simplest approach and it
//makes it easy for us to verify that the code is correct. //makes it easy for us to verify that the code is correct.

View File

@@ -2,66 +2,71 @@ package StevenDimDoors.mod_pocketDim.helpers;
import StevenDimDoors.mod_pocketDim.LinkData; import StevenDimDoors.mod_pocketDim.LinkData;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
public class yCoordHelper public class yCoordHelper
{ {
private static final int MAXIMUM_UNCOVERED_Y = 245;
public static int getFirstUncovered(LinkData pointerLink) public static int getFirstUncovered(LinkData pointerLink)
{ {
return yCoordHelper.getFirstUncovered(pointerLink.destDimID, pointerLink.destXCoord,pointerLink.destYCoord, pointerLink.destZCoord); return yCoordHelper.getFirstUncovered(
pointerLink.destDimID,
pointerLink.destXCoord,
pointerLink.destYCoord,
pointerLink.destZCoord);
} }
public static int getFirstUncovered(int worldID, int x, int yStart, int z) public static int getFirstUncovered(int worldID, int x, int yStart, int z)
{ {
if(dimHelper.getWorld(worldID)==null||dimHelper.getWorld(worldID).provider==null) if (dimHelper.getWorld(worldID) == null ||
dimHelper.getWorld(worldID).provider == null)
{ {
dimHelper.initDimension(worldID); dimHelper.initDimension(worldID);
} }
return yCoordHelper.getFirstUncovered(dimHelper.getWorld(worldID),x,yStart,z); return yCoordHelper.getFirstUncovered(dimHelper.getWorld(worldID), x, yStart, z);
} }
public static int getFirstUncovered(World world, int x, int yStart, int z) public static int getFirstUncovered(World world, int x, int yStart, int z)
{ {
int yCoord=yStart;
Chunk chunk = world.getChunkProvider().loadChunk(x >> 4, z >> 4); Chunk chunk = world.getChunkProvider().loadChunk(x >> 4, z >> 4);
int xC=(x % 16)< 0 ? (x % 16)+16 : (x % 16); int localX = x < 0 ? (x % 16) + 16 : (x % 16);
int yC=yCoord; int localZ = z < 0 ? (z % 16) + 16 : (z % 16);
int zC=(z % 16)< 0 ? (z % 16)+16 : (z % 16); int height = MAXIMUM_UNCOVERED_Y; //world.getHeight();
int y;
boolean covered = true;
boolean flag=false; for (y = yStart; y < height && covered; y++)
do
{ {
flag=false; covered = IsCoveredBlock(chunk, localX, y - 1, localZ) || IsCoveredBlock(chunk, localX, y, localZ);
if(yC>0&&chunk.getBlockID(xC, yC-1, zC)!=0)
{
if(!Block.blocksList[chunk.getBlockID(xC, yC-1, zC)].blockMaterial.isReplaceable()||Block.blocksList[chunk.getBlockID(xC, yC-1, zC)].blockMaterial.isLiquid())
{
flag=true;
}
} }
if(yC>0&&chunk.getBlockID(xC, yC, zC)!=0) return y;
{ }
if(!Block.blocksList[chunk.getBlockID(xC, yC, zC)].blockMaterial.isReplaceable()||Block.blocksList[chunk.getBlockID(xC, yC, zC)].blockMaterial.isLiquid())
public static boolean IsCoveredBlock(Chunk chunk, int localX, int y, int localZ)
{ {
int blockID;
Block block;
Material material;
flag=true; if (y < 0)
return false;
} blockID = chunk.getBlockID(localX, y, localZ);
} if (blockID == 0)
return false;
yC++; block = Block.blocksList[blockID];
} if (block == null)
while(flag&&yC<245); return false;
material = block.blockMaterial;
return yC-1; return (!material.isLiquid() && !material.isReplaceable());
} }
} }

View File

@@ -182,7 +182,7 @@ public class mod_pocketDim
blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm"); blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm");
ExitDoor = (new ExitDoor(properties.WarpDoorID, Material.wood)).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp"); ExitDoor = (new ExitDoor(properties.WarpDoorID, Material.wood)).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp");
blockRift = (new BlockRift(properties.RiftBlockID, 0, Material.air).setHardness(1.0F) .setUnlocalizedName("rift")); blockRift = (new BlockRift(properties.RiftBlockID, 0, Material.air).setHardness(1.0F) .setUnlocalizedName("rift"));
blockLimbo = (new BlockLimbo(properties.LimboBlockID, 15, Material.iron).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F)); blockLimbo = (new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F));
chaosDoor = (new ChaosDoor(properties.UnstableDoorID, Material.iron).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) ); chaosDoor = (new ChaosDoor(properties.UnstableDoorID, Material.iron).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) );
dimDoor = (new dimDoor(properties.DimensionalDoorID, Material.iron)).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor"); dimDoor = (new dimDoor(properties.DimensionalDoorID, Material.iron)).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor");
dimHatch = (new dimHatch(properties.TransTrapdoorID, 84, Material.iron)).setHardness(1.0F) .setUnlocalizedName("dimHatch"); dimHatch = (new dimHatch(properties.TransTrapdoorID, 84, Material.iron)).setHardness(1.0F) .setUnlocalizedName("dimHatch");