Implemented Scheduled Rift Regeneration
1. Implemented scheduled rift regeneration in RiftRegenerator. The previous randomized selection algorithm has been removed completely. All regeneration is scheduled now. We perform numerous checks to make sure that regenerating a rift is safe. 2. Removed FastRiftRegenerator as RiftRegenerator performs roughly the same task but with more flexibility. Updated TileEntityDimDoor to use RiftRegenerator instead for creating rifts when doors are broken. 3. Modified EventHookContainer to receive the chunk loaded event. We iterate over the list of links in a loaded chunk and schedule them for regeneration. 4. Reorganized the code in BlockRift. Divided the list of immune blocks into two lists - one for DD blocks and one for regular MC blocks. RiftRegenerator has to be able to distinguish between the two types. 5. Factored out some duplicate code from ItemRiftSignature and ItemStabilizedRiftSignature. Most of the block immunity checks were used to check if it would be safe to spawn a rift when using one of those items. BlockRift.tryPlacingRift() covers all that logic in a single function and makes the item code a little simpler.
This commit is contained in:
parent
79bd5102ba
commit
1f59dc17d9
9 changed files with 239 additions and 173 deletions
|
@ -8,6 +8,7 @@ import net.minecraft.item.ItemDoor;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldProvider;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent;
|
||||
import net.minecraftforge.client.event.sound.SoundLoadEvent;
|
||||
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.Action;
|
||||
import net.minecraftforge.event.terraingen.InitMapGenEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import StevenDimDoors.mod_pocketDim.config.DDProperties;
|
||||
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
|
||||
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.items.BaseItemDoor;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
|
||||
import StevenDimDoors.mod_pocketDim.world.PocketProvider;
|
||||
|
@ -36,18 +41,20 @@ public class EventHookContainer
|
|||
|
||||
private final DDProperties properties;
|
||||
private DDWorldProperties worldProperties;
|
||||
private RiftRegenerator regenerator;
|
||||
|
||||
public EventHookContainer(DDProperties properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setWorldProperties(DDWorldProperties worldProperties)
|
||||
public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator)
|
||||
{
|
||||
// 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.
|
||||
this.worldProperties = worldProperties;
|
||||
this.regenerator = regenerator;
|
||||
}
|
||||
|
||||
@ForgeSubscribe(priority = EventPriority.LOW)
|
||||
|
@ -217,6 +224,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)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Queue;
|
|||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.BlockFlowing;
|
||||
import net.minecraft.block.BlockFluid;
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
super(i, par2Material);
|
||||
this.setTickRandomly(true);
|
||||
this.properties = properties;
|
||||
this.modBlocksImmuneToRift = new ArrayList<Integer>();
|
||||
this.modBlocksImmuneToRift.add(properties.FabricBlockID);
|
||||
this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID);
|
||||
this.modBlocksImmuneToRift.add(properties.DimensionalDoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.WarpDoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.TransTrapdoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.UnstableDoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.RiftBlockID);
|
||||
this.modBlocksImmuneToRift.add(properties.TransientDoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
|
||||
this.modBlocksImmuneToRift.add(properties.GoldenDoorID);
|
||||
|
||||
this.blocksImmuneToRift = new ArrayList<Integer>();
|
||||
this.blocksImmuneToRift.add(properties.FabricBlockID);
|
||||
this.blocksImmuneToRift.add(properties.PermaFabricBlockID);
|
||||
this.blocksImmuneToRift.add(properties.DimensionalDoorID);
|
||||
this.blocksImmuneToRift.add(properties.WarpDoorID);
|
||||
this.blocksImmuneToRift.add(properties.TransTrapdoorID);
|
||||
this.blocksImmuneToRift.add(properties.UnstableDoorID);
|
||||
this.blocksImmuneToRift.add(properties.RiftBlockID);
|
||||
this.blocksImmuneToRift.add(properties.TransientDoorID);
|
||||
this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
|
||||
this.blocksImmuneToRift.add(properties.GoldenDoorID);
|
||||
|
||||
this.blocksImmuneToRift.add(Block.blockLapis.blockID);
|
||||
this.blocksImmuneToRift.add(Block.blockIron.blockID);
|
||||
this.blocksImmuneToRift.add(Block.blockGold.blockID);
|
||||
|
@ -220,7 +223,7 @@ public class BlockRift extends Block implements ITileEntityProvider
|
|||
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)
|
||||
&& !(Block.blocksList[blockID] instanceof BlockFlowing ||
|
||||
|
@ -251,16 +254,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)
|
||||
{
|
||||
|
@ -412,6 +405,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)
|
||||
{
|
||||
|
@ -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
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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 destinationDimension = PocketManager.getDimensionData(world);
|
||||
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);
|
||||
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
//Try placing a rift at the destination point
|
||||
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
|
||||
{
|
||||
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
|
||||
}
|
||||
// Try placing a rift at the destination point
|
||||
mod_pocketDim.blockRift.tryPlacingRift(world, 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());
|
||||
if (sourceWorld != null &&
|
||||
!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.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
if (!player.capabilities.isCreativeMode)
|
||||
{
|
||||
stack.stackSize--;
|
||||
}
|
||||
clearSource(stack);
|
||||
mod_pocketDim.sendChat(player,("Rift Created"));
|
||||
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1);
|
||||
mod_pocketDim.sendChat(player, "Rift Created");
|
||||
world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -90,19 +90,13 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
|
|||
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
// Try placing a rift at the destination point
|
||||
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
|
||||
{
|
||||
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
|
||||
}
|
||||
mod_pocketDim.blockRift.tryPlacingRift(world, 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());
|
||||
if (sourceWorld != null &&
|
||||
!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.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
mod_pocketDim.sendChat(player, "Rift Created");
|
||||
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.
|
||||
setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world));
|
||||
mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature");
|
||||
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1);
|
||||
mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature");
|
||||
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -148,14 +142,11 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
|
|||
// Only the source-to-destination link is needed.
|
||||
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL, source.getOrientation());
|
||||
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());
|
||||
if (sourceWorld != null &&
|
||||
!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.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -53,7 +53,6 @@ import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
|
|||
import StevenDimDoors.mod_pocketDim.items.ItemWorldThread;
|
||||
import StevenDimDoors.mod_pocketDim.items.itemRiftRemover;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
|
||||
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
|
||||
|
@ -143,8 +142,7 @@ public class mod_pocketDim
|
|||
public static DDProperties properties;
|
||||
public static DDWorldProperties worldProperties;
|
||||
public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later.
|
||||
private static RiftRegenerator riftRegenerator;
|
||||
public static FastRiftRegenerator fastRiftRegenerator;
|
||||
public static RiftRegenerator riftRegenerator;
|
||||
public static GatewayGenerator gatewayGenerator;
|
||||
public static DeathTracker deathTracker;
|
||||
private static ServerTickHandler serverTickHandler;
|
||||
|
@ -325,6 +323,9 @@ public class mod_pocketDim
|
|||
// Unregister all tick receivers from serverTickHandler to avoid leaking
|
||||
// scheduled tasks between single-player game sessions
|
||||
serverTickHandler.unregisterReceivers();
|
||||
spawner = null;
|
||||
riftRegenerator = null;
|
||||
limboDecayScheduler = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -339,7 +340,6 @@ public class mod_pocketDim
|
|||
|
||||
// Load the config file that's specific to this world
|
||||
worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg"));
|
||||
hooks.setWorldProperties(worldProperties);
|
||||
|
||||
// Initialize a new DeathTracker
|
||||
deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt");
|
||||
|
@ -347,9 +347,10 @@ public class mod_pocketDim
|
|||
// Register regular tick receivers
|
||||
// CustomLimboPopulator should be initialized before any provider instances are created
|
||||
spawner = new CustomLimboPopulator(serverTickHandler, properties);
|
||||
riftRegenerator = new RiftRegenerator(serverTickHandler);
|
||||
riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift);
|
||||
limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay);
|
||||
fastRiftRegenerator = new FastRiftRegenerator(serverTickHandler);
|
||||
|
||||
hooks.setSessionFields(worldProperties, riftRegenerator);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -1,56 +1,113 @@
|
|||
package StevenDimDoors.mod_pocketDim.ticking;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
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.NewDimData;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||
|
||||
public class RiftRegenerator implements IRegularTickReceiver {
|
||||
|
||||
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
|
||||
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
|
||||
// Ranges of regeneration delays, in seconds
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +1,13 @@
|
|||
package StevenDimDoors.mod_pocketDim.tileentities;
|
||||
|
||||
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.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet130UpdateSign;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
|
||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||
import StevenDimDoors.mod_pocketDim.core.DimLink;
|
||||
import StevenDimDoors.mod_pocketDim.core.PocketManager;
|
||||
|
||||
public class TileEntityDimDoor extends DDTileEntityBase
|
||||
{
|
||||
|
@ -28,25 +24,26 @@ public class TileEntityDimDoor extends DDTileEntityBase
|
|||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket()
|
||||
{
|
||||
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null)
|
||||
{
|
||||
return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Packet getDescriptionPacket()
|
||||
{
|
||||
DimLink link = PocketManager.getLink(xCoord, yCoord, zCoord, worldObj);
|
||||
if (link != null)
|
||||
{
|
||||
return ServerPacketHandler.createLinkPacket(link.link());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate()
|
||||
{
|
||||
this.tileEntityInvalid = true;
|
||||
|
||||
if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote)
|
||||
super.invalidate();
|
||||
if (!worldObj.isRemote && worldObj.getBlockId(xCoord, yCoord, zCoord) == 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +71,7 @@ public class TileEntityDimDoor extends DDTileEntityBase
|
|||
public void writeToNBT(NBTTagCompound nbt)
|
||||
{
|
||||
super.writeToNBT(nbt);
|
||||
|
||||
|
||||
nbt.setBoolean("openOrClosed", this.openOrClosed);
|
||||
nbt.setBoolean("hasExit", this.hasExit);
|
||||
nbt.setInteger("orientation", this.orientation);
|
||||
|
|
Loading…
Reference in a new issue