Fixed Slow Rift Regeneration and Various Improvements #173

Merged
SenseiKiwi merged 12 commits from master into master 2014-07-11 20:12:08 +00:00
9 changed files with 239 additions and 173 deletions
Showing only changes of commit 1f59dc17d9 - Show all commits

View File

@@ -8,6 +8,7 @@ import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldProvider; import net.minecraft.world.WorldProvider;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent; import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent;
import net.minecraftforge.client.event.sound.SoundLoadEvent; import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.event.EventPriority; import net.minecraftforge.event.EventPriority;
@@ -17,12 +18,16 @@ import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.terraingen.InitMapGenEvent; import net.minecraftforge.event.terraingen.InitMapGenEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import StevenDimDoors.mod_pocketDim.config.DDProperties; import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties; import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.BaseItemDoor; import StevenDimDoors.mod_pocketDim.items.BaseItemDoor;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.world.LimboProvider; import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider; import StevenDimDoors.mod_pocketDim.world.PocketProvider;
@@ -36,18 +41,20 @@ public class EventHookContainer
private final DDProperties properties; private final DDProperties properties;
private DDWorldProperties worldProperties; private DDWorldProperties worldProperties;
private RiftRegenerator regenerator;
public EventHookContainer(DDProperties properties) public EventHookContainer(DDProperties properties)
{ {
this.properties = properties; this.properties = properties;
} }
public void setWorldProperties(DDWorldProperties worldProperties) public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator)
{ {
// SenseiKiwi: // SenseiKiwi:
// Why have a setter rather than accessing mod_pocketDim.worldProperties? // Why have a setter rather than accessing mod_pocketDim directly?
// I want to make this dependency explicit in our code. // I want to make this dependency explicit in our code.
this.worldProperties = worldProperties; this.worldProperties = worldProperties;
this.regenerator = regenerator;
} }
@ForgeSubscribe(priority = EventPriority.LOW) @ForgeSubscribe(priority = EventPriority.LOW)
@@ -218,6 +225,22 @@ public class EventHookContainer
} }
} }
@ForgeSubscribe
public void onChunkLoad(ChunkEvent.Load event)
{
// Schedule rift regeneration for any links located in this chunk.
// This event runs on both the client and server. Allow server only.
Chunk chunk = event.getChunk();
if (!chunk.worldObj.isRemote)
{
NewDimData dimension = PocketManager.getDimensionData(chunk.worldObj);
for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition))
{
regenerator.scheduleSlowRegeneration(link);
}
}
}
public void playMusicForDim(World world) public void playMusicForDim(World world)
{ {
if (world.isRemote) if (world.isRemote)

View File

@@ -7,6 +7,7 @@ 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;
@@ -47,25 +48,27 @@ public class BlockRift extends Block implements ITileEntityProvider
public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000; public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000;
private final DDProperties properties; private final DDProperties properties;
private final ArrayList<Integer> blocksImmuneToRift; private final ArrayList<Integer> blocksImmuneToRift; // List of Vanilla blocks immune to rifts
private final ArrayList<Integer> modBlocksImmuneToRift; // List of DD blocks immune to rifts
public BlockRift(int i, int j, Material par2Material, DDProperties properties) public BlockRift(int i, int j, Material par2Material, DDProperties properties)
{ {
super(i, par2Material); super(i, par2Material);
this.setTickRandomly(true); this.setTickRandomly(true);
this.properties = properties; this.properties = properties;
this.blocksImmuneToRift = new ArrayList<Integer>(); this.modBlocksImmuneToRift = new ArrayList<Integer>();
this.blocksImmuneToRift.add(properties.FabricBlockID); this.modBlocksImmuneToRift.add(properties.FabricBlockID);
this.blocksImmuneToRift.add(properties.PermaFabricBlockID); this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID);
this.blocksImmuneToRift.add(properties.DimensionalDoorID); this.modBlocksImmuneToRift.add(properties.DimensionalDoorID);
this.blocksImmuneToRift.add(properties.WarpDoorID); this.modBlocksImmuneToRift.add(properties.WarpDoorID);
this.blocksImmuneToRift.add(properties.TransTrapdoorID); this.modBlocksImmuneToRift.add(properties.TransTrapdoorID);
this.blocksImmuneToRift.add(properties.UnstableDoorID); this.modBlocksImmuneToRift.add(properties.UnstableDoorID);
this.blocksImmuneToRift.add(properties.RiftBlockID); this.modBlocksImmuneToRift.add(properties.RiftBlockID);
this.blocksImmuneToRift.add(properties.TransientDoorID); this.modBlocksImmuneToRift.add(properties.TransientDoorID);
this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID); this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.blocksImmuneToRift.add(properties.GoldenDoorID); this.modBlocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift = new ArrayList<Integer>();
this.blocksImmuneToRift.add(Block.blockLapis.blockID); this.blocksImmuneToRift.add(Block.blockLapis.blockID);
this.blocksImmuneToRift.add(Block.blockIron.blockID); this.blocksImmuneToRift.add(Block.blockIron.blockID);
this.blocksImmuneToRift.add(Block.blockGold.blockID); this.blocksImmuneToRift.add(Block.blockGold.blockID);
@@ -220,7 +223,7 @@ public class BlockRift extends Block implements ITileEntityProvider
return targets; return targets;
} }
private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random) public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
{ {
if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance) if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance)
&& !(Block.blocksList[blockID] instanceof BlockFlowing || && !(Block.blocksList[blockID] instanceof BlockFlowing ||
@@ -252,16 +255,6 @@ public class BlockRift extends Block implements ITileEntityProvider
} }
} }
public void regenerateRift(World world, int x, int y, int z, Random random)
{
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4))
{
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, properties.RiftBlockID))
dropWorldThread(blockID, world, x, y, z, random);
}
}
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random) public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
{ {
int x, y, z, blockID; int x, y, z, blockID;
@@ -413,6 +406,15 @@ public class BlockRift extends Block implements ITileEntityProvider
} }
} }
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, mod_pocketDim.blockRift.blockID);
}
return false;
}
public boolean isBlockImmune(World world, int x, int y, int z) public boolean isBlockImmune(World world, int x, int y, int z)
{ {
Block block = Block.blocksList[world.getBlockId(x, y, z)]; Block block = Block.blocksList[world.getBlockId(x, y, z)];
@@ -424,7 +426,21 @@ public class BlockRift extends Block implements ITileEntityProvider
// is designed to receive an entity, the source of the blast. We have no entity so // 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. // I've set this to access blockResistance directly. Might need changing later.
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID)); return (block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block.blockID) ||
blocksImmuneToRift.contains(block.blockID));
}
return false;
}
public boolean isModBlockImmune(World world, int x, int y, int z)
{
// Check whether the block at the specified location is one of the
// rift-resistant blocks from DD.
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (block != null)
{
return modBlocksImmuneToRift.contains(block.blockID);
} }
return false; return false;
} }

View File

@@ -71,7 +71,8 @@ public class ItemRiftSignature extends Item
int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
if (source != null) if (source != null)
{ {
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints. // The link was used before and already has an endpoint stored.
// Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension()); NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.getDimensionData(world); NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation()); DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
@@ -79,27 +80,21 @@ public class ItemRiftSignature extends Item
destinationDimension.setLinkDestination(link, x, adjustedY, z); destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
//Try placing a rift at the destination point // Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
//Try placing a rift at the source point, but check if its world is loaded first // Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null && mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
if (!player.capabilities.isCreativeMode) if (!player.capabilities.isCreativeMode)
{ {
stack.stackSize--; stack.stackSize--;
} }
clearSource(stack); clearSource(stack);
mod_pocketDim.sendChat(player,("Rift Created")); mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1); world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1);
} }
else else
{ {

View File

@@ -90,19 +90,13 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ()); sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point // Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z)) mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
} }
// Try placing a rift at the source point, but check if its world is loaded first // Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null && mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
mod_pocketDim.sendChat(player, "Rift Created"); mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
@@ -111,8 +105,8 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
{ {
// The link signature has not been used. Store its current target as the first location. // The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world)); setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world));
mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature"); mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1); world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1);
} }
return true; return true;
} }
@@ -149,13 +143,10 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL, source.getOrientation()); link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z); destinationDimension.setLinkDestination(link, x, adjustedY, z);
// Try placing a rift at the source point, but check if its world is loaded first // Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id()); World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null && mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
// This call doesn't seem to be working... // This call doesn't seem to be working...
world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1); world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);

View File

@@ -53,7 +53,6 @@ import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWorldThread; import StevenDimDoors.mod_pocketDim.items.ItemWorldThread;
import StevenDimDoors.mod_pocketDim.items.itemRiftRemover; import StevenDimDoors.mod_pocketDim.items.itemRiftRemover;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator; import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler; import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith; import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator; import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
@@ -143,8 +142,7 @@ public class mod_pocketDim
public static DDProperties properties; public static DDProperties properties;
public static DDWorldProperties worldProperties; public static DDWorldProperties worldProperties;
public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later. public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later.
private static RiftRegenerator riftRegenerator; public static RiftRegenerator riftRegenerator;
public static FastRiftRegenerator fastRiftRegenerator;
public static GatewayGenerator gatewayGenerator; public static GatewayGenerator gatewayGenerator;
public static DeathTracker deathTracker; public static DeathTracker deathTracker;
private static ServerTickHandler serverTickHandler; private static ServerTickHandler serverTickHandler;
@@ -325,6 +323,9 @@ public class mod_pocketDim
// Unregister all tick receivers from serverTickHandler to avoid leaking // Unregister all tick receivers from serverTickHandler to avoid leaking
// scheduled tasks between single-player game sessions // scheduled tasks between single-player game sessions
serverTickHandler.unregisterReceivers(); serverTickHandler.unregisterReceivers();
spawner = null;
riftRegenerator = null;
limboDecayScheduler = null;
} }
catch (Exception e) catch (Exception e)
{ {
@@ -339,7 +340,6 @@ public class mod_pocketDim
// Load the config file that's specific to this world // Load the config file that's specific to this world
worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg")); worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg"));
hooks.setWorldProperties(worldProperties);
// Initialize a new DeathTracker // Initialize a new DeathTracker
deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt"); deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt");
@@ -347,9 +347,10 @@ public class mod_pocketDim
// Register regular tick receivers // Register regular tick receivers
// CustomLimboPopulator should be initialized before any provider instances are created // CustomLimboPopulator should be initialized before any provider instances are created
spawner = new CustomLimboPopulator(serverTickHandler, properties); spawner = new CustomLimboPopulator(serverTickHandler, properties);
riftRegenerator = new RiftRegenerator(serverTickHandler); riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift);
limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay); limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay);
fastRiftRegenerator = new FastRiftRegenerator(serverTickHandler);
hooks.setSessionFields(worldProperties, riftRegenerator);
} }
@EventHandler @EventHandler

View File

@@ -1,54 +0,0 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class FastRiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks
private static Random random = new Random();
private ArrayList<Point4D> locationsToRegen = new ArrayList<Point4D>();
public FastRiftRegenerator(IRegularTickSender sender)
{
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
regenerateScheduledRifts();
}
public void regenerateScheduledRifts()
{
if (!locationsToRegen.isEmpty())
{
@SuppressWarnings("cast")
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Point4D point: locationsToRegen)
{
if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null)
{
World world = DimensionManager.getWorld(point.getDimension());
mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random);
}
}
locationsToRegen.clear();
}
}
public void registerRiftForRegen(int x, int y, int z, int dimID)
{
this.locationsToRegen.add(new Point4D(x, y, z, dimID));
}
}

View File

@@ -1,56 +1,113 @@
package StevenDimDoors.mod_pocketDim.ticking; package StevenDimDoors.mod_pocketDim.ticking;
import java.util.Arrays; import java.util.PriorityQueue;
import java.util.List;
import java.util.Random; import java.util.Random;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim; import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D; import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftRegenerator implements IRegularTickReceiver { public class RiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks // Ranges of regeneration delays, in seconds
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5; private static final int MIN_FAST_DELAY = 1;
private static final int MAX_FAST_DELAY = 3;
private static final int MIN_SLOW_DELAY = 5;
private static final int MAX_SLOW_DELAY = 15;
private static final int MIN_RESCHEDULE_DELAY = 4 * 60;
private static final int MAX_RESCHEDULE_DELAY = 6 * 60;
private static final int TICKS_PER_SECOND = 20;
private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick
private static Random random = new Random(); private static Random random = new Random();
public RiftRegenerator(IRegularTickSender sender) private long tickCount = 0;
private PriorityQueue<RiftTicket> ticketQueue;
private BlockRift blockRift;
public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift)
{ {
this.ticketQueue = new PriorityQueue<RiftTicket>();
this.blockRift = blockRift;
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false); sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
} }
@Override @Override
public void notifyTick() public void notifyTick()
{ {
regenerateRiftsInLoadedWorlds(); processTicketQueue();
tickCount++;
} }
private static void regenerateRiftsInLoadedWorlds() public void scheduleSlowRegeneration(DimLink link)
{ {
// Regenerate rifts that have been replaced (not permanently removed) by players scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
// Only do this in dimensions that are currently loaded
List<Integer> loadedWorlds = Arrays.asList(DimensionManager.getIDs());
for (Integer dimensionID : loadedWorlds)
{
NewDimData dimension = PocketManager.getDimensionData(dimensionID);
if (dimension.linkCount() > 0)
{
World world = DimensionManager.getWorld(dimension.id());
if (world != null)
{
for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++)
{
DimLink link = dimension.getRandomLink();
Point4D source = link.source();
mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random);
}
}
}
}
} }
public void scheduleFastRegeneration(DimLink link)
{
scheduleRegeneration(link, MIN_FAST_DELAY, MAX_FAST_DELAY);
}
private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay)
{
int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND);
ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay));
}
private void processTicketQueue()
{
RiftTicket ticket;
while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount)
{
ticket = ticketQueue.remove();
regenerateRift(ticket.location());
}
}
private void regenerateRift(Point4D location)
{
int x = location.getX();
int y = location.getY();
int z = location.getZ();
// Try to regenerate a rift, or possibly reschedule its regeneration.
// The world for the given location must be loaded.
World world = DimensionManager.getWorld(location.getDimension());
if (world == null)
return;
// There must be a link at the given location.
DimLink link = PocketManager.getLink(location);
if (link == null)
return;
// The chunk at the given location must be loaded.
// FIXME: I can't figure out how to check if a chunk is loaded.
// Will only check if the chunk exists for now. This isn't a big deal. --SenseiKiwi
if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4))
return;
// If the location is occupied by an immune DD block, then don't regenerate.
if (blockRift.isModBlockImmune(world, x, y, z))
return;
// If the location is occupied by an immune block, then reschedule.
if (blockRift.isBlockImmune(world, x, y, z))
{
scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY);
}
else
{
// All of the necessary conditions have been met. Restore the rift!
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, blockRift.blockID))
blockRift.dropWorldThread(blockID, world, x, y, z, random);
}
}
} }

View File

@@ -0,0 +1,40 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftTicket implements Comparable<RiftTicket> {
private long timestamp;
private Point4D location;
public RiftTicket(Point4D location, long timestamp)
{
this.timestamp = timestamp;
this.location = location;
}
@Override
public int compareTo(RiftTicket other)
{
if (this.timestamp < other.timestamp)
{
return -1;
}
else if (this.timestamp > other.timestamp)
{
return 1;
}
return 0;
}
public long timestamp()
{
return timestamp;
}
public Point4D location()
{
return location;
}
}

View File

@@ -1,17 +1,13 @@
package StevenDimDoors.mod_pocketDim.tileentities; package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.Random; import java.util.Random;
import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet130UpdateSign; import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
import net.minecraft.network.packet.Packet250CustomPayload; import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import net.minecraft.tileentity.TileEntity; import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class TileEntityDimDoor extends DDTileEntityBase public class TileEntityDimDoor extends DDTileEntityBase
{ {
@@ -28,25 +24,26 @@ public class TileEntityDimDoor extends DDTileEntityBase
} }
@Override @Override
public Packet getDescriptionPacket() public Packet getDescriptionPacket()
{ {
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj);
{ if (link != null)
return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link()); {
} return ServerPacketHandler.createLinkPacket(link.link());
return null; }
} return null;
}
@Override @Override
public void invalidate() public void invalidate()
{ {
this.tileEntityInvalid = true; super.invalidate();
if (!worldObj.isRemote && worldObj.getBlockId(xCoord, yCoord, zCoord) == 0)
if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote)
{ {
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj);
if (link != null)
{ {
mod_pocketDim.fastRiftRegenerator.registerRiftForRegen(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId); mod_pocketDim.riftRegenerator.scheduleFastRegeneration(link);
} }
} }
} }