2013-02-18 03:46:16 +01:00
|
|
|
package StevenDimDoors.mod_pocketDim;
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
import java.util.ArrayList;
|
2013-02-18 03:46:16 +01:00
|
|
|
import java.util.EnumSet;
|
|
|
|
import java.util.Random;
|
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2013-07-26 07:09:46 +02:00
|
|
|
import net.minecraft.server.MinecraftServer;
|
|
|
|
import net.minecraft.world.GameRules;
|
2013-07-25 07:38:58 +02:00
|
|
|
import net.minecraft.world.World;
|
2013-06-10 23:03:52 +02:00
|
|
|
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
|
2013-07-12 05:58:59 +02:00
|
|
|
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
|
|
|
|
import StevenDimDoors.mod_pocketDim.ticking.MobObelisk;
|
2013-02-18 03:46:16 +01:00
|
|
|
import cpw.mods.fml.common.FMLCommonHandler;
|
|
|
|
import cpw.mods.fml.common.ITickHandler;
|
|
|
|
import cpw.mods.fml.common.TickType;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-02-18 03:46:16 +01:00
|
|
|
public class CommonTickHandler implements ITickHandler
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
private int tickCount = 0;
|
2013-06-14 01:01:54 +02:00
|
|
|
private static DDProperties properties = null;
|
2013-07-25 07:38:58 +02:00
|
|
|
public static ArrayList<int[]> chunksToPopulate = new ArrayList<int[]>();
|
|
|
|
|
|
|
|
private static final Random rand = new Random();
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
public static final int MAX_MONOLITH_SPAWNING_CHANCE = 100;
|
2013-07-26 07:09:46 +02:00
|
|
|
private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick";
|
|
|
|
private static final String MOB_SPAWNING_RULE = "doMobSpawning";
|
2013-07-12 05:58:59 +02:00
|
|
|
private static final int MAX_MONOLITH_SPAWN_Y = 245;
|
|
|
|
private static final int CHUNK_SIZE = 16;
|
2013-07-25 07:38:58 +02:00
|
|
|
private static final int RIFT_REGENERATION_INTERVAL = 100; //Regenerate random rifts every 100 ticks
|
2013-07-26 05:54:30 +02:00
|
|
|
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks
|
2013-07-12 05:58:59 +02:00
|
|
|
|
2013-06-14 01:01:54 +02:00
|
|
|
public CommonTickHandler()
|
|
|
|
{
|
|
|
|
if (properties == null)
|
|
|
|
properties = DDProperties.instance();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void tickStart(EnumSet<TickType> type, Object... tickData)
|
|
|
|
{
|
|
|
|
if (type.equals(EnumSet.of(TickType.SERVER)))
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
onServerTick();
|
2013-06-14 01:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void tickEnd(EnumSet<TickType> type, Object... tickData)
|
|
|
|
{
|
|
|
|
if (type.equals(EnumSet.of(TickType.SERVER)))
|
|
|
|
{
|
2013-07-26 07:09:46 +02:00
|
|
|
if(!CommonTickHandler.chunksToPopulate.isEmpty() && IsMobSpawningAllowed())
|
2013-07-12 05:58:59 +02:00
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
//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)
|
2013-07-12 05:58:59 +02:00
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
if(chunkData[0] == properties.LimboDimensionID)
|
2013-07-12 05:58:59 +02:00
|
|
|
{
|
|
|
|
this.placeMonolithsInLimbo(chunkData[0], chunkData[1], chunkData[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.placeMonolithsInPockets(chunkData[0], chunkData[1], chunkData[2]);
|
|
|
|
}
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CommonTickHandler.chunksToPopulate.clear();
|
2013-06-14 01:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
@Override
|
|
|
|
public EnumSet<TickType> ticks()
|
2013-06-14 01:01:54 +02:00
|
|
|
{
|
|
|
|
return EnumSet.of(TickType.SERVER);
|
|
|
|
}
|
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
@Override
|
2013-06-14 01:01:54 +02:00
|
|
|
public String getLabel()
|
|
|
|
{
|
2013-07-26 07:09:46 +02:00
|
|
|
return PROFILING_LABEL; //Used for profiling!
|
2013-06-14 01:01:54 +02:00
|
|
|
}
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
private void placeMonolithsInPockets(int worldID, int chunkX, int chunkZ)
|
|
|
|
{
|
|
|
|
World worldObj = dimHelper.getWorld(worldID);
|
|
|
|
DimData dimData = dimHelper.dimList.get(worldObj.provider.dimensionId);
|
2013-07-25 07:38:58 +02:00
|
|
|
int sanity = 0;
|
|
|
|
int blockID = 0;
|
|
|
|
boolean didSpawn=false;
|
|
|
|
|
|
|
|
if (dimData == null ||
|
|
|
|
dimData.dungeonGenerator == null ||
|
|
|
|
dimData.dungeonGenerator.isOpen)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
//The following initialization code is based on code from ChunkProviderGenerate.
|
|
|
|
//It makes our generation depend on the world seed.
|
|
|
|
Random random = new Random(worldObj.getSeed());
|
2013-07-25 07:38:58 +02:00
|
|
|
long factorA = random.nextLong() / 2L * 2L + 1L;
|
|
|
|
long factorB = random.nextLong() / 2L * 2L + 1L;
|
|
|
|
random.setSeed(chunkX * factorA + chunkZ * factorB ^ worldObj.getSeed());
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
int x, y, z;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
//Select a random column within the chunk
|
|
|
|
x = chunkX * CHUNK_SIZE + random.nextInt(CHUNK_SIZE);
|
|
|
|
z = chunkZ * CHUNK_SIZE + random.nextInt(CHUNK_SIZE);
|
|
|
|
y = MAX_MONOLITH_SPAWN_Y;
|
|
|
|
blockID = worldObj.getBlockId(x, y, z);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
while (blockID == 0 &&y>0)
|
|
|
|
{
|
|
|
|
y--;
|
|
|
|
blockID = worldObj.getBlockId(x, y, z);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
}
|
2013-07-18 07:20:12 +02:00
|
|
|
while((blockID == mod_pocketDim.blockDimWall.blockID||blockID == mod_pocketDim.blockDimWallPerm.blockID)&&y>0)
|
2013-07-12 05:58:59 +02:00
|
|
|
{
|
|
|
|
y--;
|
|
|
|
blockID = worldObj.getBlockId(x, y, z);
|
|
|
|
}
|
|
|
|
while (blockID == 0 &&y>0)
|
|
|
|
{
|
|
|
|
y--;
|
|
|
|
blockID = worldObj.getBlockId(x, y, z);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
}
|
|
|
|
if(y > 0)
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
|
|
|
|
int jumpSanity=0;
|
|
|
|
int jumpHeight=0;
|
|
|
|
do
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
jumpHeight = y+random.nextInt(10);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
jumpSanity++;
|
|
|
|
}
|
|
|
|
while(!worldObj.isAirBlock(x,jumpHeight+6 , z)&&jumpSanity<20);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
|
|
|
|
Entity mob = new MobObelisk(worldObj);
|
|
|
|
mob.setLocationAndAngles(x, jumpHeight, z, 1, 1);
|
|
|
|
worldObj.spawnEntityInWorld(mob);
|
|
|
|
didSpawn=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
sanity++;
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
}
|
|
|
|
while (sanity<5&&!didSpawn);
|
|
|
|
}
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
private void placeMonolithsInLimbo(int worldID, int var2, int var3)
|
|
|
|
{
|
|
|
|
World world = dimHelper.getWorld(worldID);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
if (rand.nextInt(MAX_MONOLITH_SPAWNING_CHANCE) < properties.MonolithSpawningChance)
|
|
|
|
{
|
|
|
|
int y =0;
|
|
|
|
int x = var2*16 + rand.nextInt(16);
|
|
|
|
int z = var3*16 + rand.nextInt(16);
|
|
|
|
int yTest;
|
|
|
|
do
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
x = var2*16 + rand.nextInt(16);
|
|
|
|
z = var3*16 + rand.nextInt(16);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
while(world.getBlockId(x, y, z)==0&&y<255)
|
|
|
|
{
|
|
|
|
y++;
|
|
|
|
}
|
|
|
|
y = yCoordHelper.getFirstUncovered(world,x , y+2, z);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
yTest=yCoordHelper.getFirstUncovered(world,x , y+5, z);
|
|
|
|
if(yTest>245)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
int jumpSanity=0;
|
|
|
|
int jumpHeight=0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
jumpHeight = y+rand.nextInt(25);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
jumpSanity++;
|
|
|
|
}
|
|
|
|
while(!world.isAirBlock(x,jumpHeight+6 , z)&&jumpSanity<20);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
Entity mob = new MobObelisk(world);
|
|
|
|
mob.setLocationAndAngles(x, jumpHeight, z, 1, 1);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
world.spawnEntityInWorld(mob);
|
2013-07-25 07:38:58 +02:00
|
|
|
|
2013-07-12 05:58:59 +02:00
|
|
|
}
|
|
|
|
while (yTest > y);
|
|
|
|
}
|
|
|
|
}
|
2013-07-26 07:09:46 +02:00
|
|
|
|
|
|
|
private static boolean IsMobSpawningAllowed()
|
|
|
|
{
|
|
|
|
//This function is used to retrieve the value of doMobSpawning. The code is the same
|
|
|
|
//as the code used by Minecraft. Jaitsu requested this to make testing easier. ~SenseiKiwi
|
|
|
|
|
|
|
|
GameRules rules = MinecraftServer.getServer().worldServerForDimension(0).getGameRules();
|
|
|
|
return rules.getGameRuleBooleanValue(MOB_SPAWNING_RULE);
|
|
|
|
}
|
2013-07-25 06:12:13 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
private void onServerTick()
|
|
|
|
{
|
2013-07-25 23:25:43 +02:00
|
|
|
tickCount++; //There is no need to reset the counter. Let it overflow. Really.
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
if (tickCount % RIFT_REGENERATION_INTERVAL == 0)
|
|
|
|
{
|
|
|
|
regenerateRifts();
|
|
|
|
}
|
2013-07-25 23:25:43 +02:00
|
|
|
|
2013-07-26 05:54:30 +02:00
|
|
|
if (tickCount % LIMBO_DECAY_INTERVAL == 0)
|
|
|
|
{
|
|
|
|
LimboDecay.ApplyRandomFastDecay();
|
|
|
|
}
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
if (mod_pocketDim.teleTimer > 0)
|
|
|
|
{
|
|
|
|
mod_pocketDim.teleTimer--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void regenerateRifts()
|
2013-06-14 01:01:54 +02:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2013-07-25 23:25:43 +02:00
|
|
|
//Regenerate rifts that have been replaced (not permanently removed) by players
|
2013-07-25 07:38:58 +02:00
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
while (i < 15 && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER)
|
2013-06-14 01:01:54 +02:00
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
i++;
|
|
|
|
LinkData link;
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
//actually gets the random rift based on the size of the list
|
|
|
|
link = (LinkData) dimHelper.instance.getRandomLinkData(true);
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
if(link!=null)
|
|
|
|
{
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
if (dimHelper.getWorld(link.locDimID)!=null)
|
2013-06-14 01:01:54 +02:00
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
World world = dimHelper.getWorld(link.locDimID);
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
int blocktoReplace = world.getBlockId(link.locXCoord, link.locYCoord, link.locZCoord);
|
2013-06-14 01:01:54 +02:00
|
|
|
|
2013-07-25 07:38:58 +02:00
|
|
|
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)
|
2013-06-14 01:01:54 +02:00
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
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;
|
2013-06-14 01:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2013-07-25 07:38:58 +02:00
|
|
|
System.out.println("An exception occurred in CommonTickHandler.onServerTick():");
|
2013-06-30 21:53:02 +02:00
|
|
|
e.printStackTrace();
|
2013-06-14 01:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
2013-06-30 21:53:02 +02:00
|
|
|
}
|