Initial attempt at chunkloading explosions
This fixes a bug where leaving the chunk shortly after an explosion will cause the explosion to either not happen, or do very little. Currently this functionality only applies to nuclear explosions. When the EntityNuclearExplosion does its first tick we grab a ticket from ForgeChunkManager and use it to load the chunk that will contain the EntityFalloutRain. The ticket is then passed to the EntityFalloutRain which will unload the chunk when it finishes its work. Doing it this way will almost certianly add race conditions but it works as a proof of concept. Ideally I imagine we would wnat to have some class that will keep track of loaded explosions and make sure that they are unloaded properly even if the entity somehow despawns. I also did not impliment anything in the chunk loading callback. As far as I understand, we would need to store the loaded chunks there so if the server dies in the middle of an explosion, it will be reloaded when the server comes back up.
This commit is contained in:
parent
d8d09ec90c
commit
aad46297f4
4 changed files with 74 additions and 4 deletions
|
@ -11,10 +11,12 @@ import trinity.gui.GuiHandlerRegistry;
|
||||||
import trinity.init.ModBlocks;
|
import trinity.init.ModBlocks;
|
||||||
import trinity.init.TrinityRecipes;
|
import trinity.init.TrinityRecipes;
|
||||||
import trinity.radiation.RadiationHandler;
|
import trinity.radiation.RadiationHandler;
|
||||||
|
import trinity.world.ChunkLoader;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
//import nca.worldgen.OreGen;
|
//import nca.worldgen.OreGen;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.common.ForgeChunkManager;
|
||||||
import net.minecraftforge.fluids.FluidRegistry;
|
import net.minecraftforge.fluids.FluidRegistry;
|
||||||
import net.minecraftforge.fml.common.Loader;
|
import net.minecraftforge.fml.common.Loader;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
@ -59,6 +61,7 @@ public class Trinity {
|
||||||
TCLoaded = Loader.isModLoaded("thaumcraft");
|
TCLoaded = Loader.isModLoaded("thaumcraft");
|
||||||
ICBMLoaded = Loader.isModLoaded("icbmclassic");
|
ICBMLoaded = Loader.isModLoaded("icbmclassic");
|
||||||
QMDLoaded = Loader.isModLoaded("qmd");
|
QMDLoaded = Loader.isModLoaded("qmd");
|
||||||
|
ForgeChunkManager.setForcedChunkLoadingCallback(Trinity.instance, ChunkLoader.getInstance());
|
||||||
TrinityConfig.preInit();
|
TrinityConfig.preInit();
|
||||||
proxy.preInit(preEvent);
|
proxy.preInit(preEvent);
|
||||||
proxy.registerRenderInfo();
|
proxy.registerRenderInfo();
|
||||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.util.EnumParticleTypes;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.util.math.BlockPos.MutableBlockPos;
|
import net.minecraft.util.math.BlockPos.MutableBlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
//import net.minecraft.util.AxisAlignedBB;
|
//import net.minecraft.util.AxisAlignedBB;
|
||||||
|
@ -44,6 +45,7 @@ import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraftforge.fluids.BlockFluidClassic;
|
import net.minecraftforge.fluids.BlockFluidClassic;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
import net.minecraftforge.common.ForgeChunkManager;
|
||||||
//import thaumcraft.api.aura.AuraHelper;
|
//import thaumcraft.api.aura.AuraHelper;
|
||||||
//import thaumcraft.api.blocks.BlocksTC;
|
//import thaumcraft.api.blocks.BlocksTC;
|
||||||
import trinity.Trinity;
|
import trinity.Trinity;
|
||||||
|
@ -67,6 +69,9 @@ public class EntityFalloutRain extends Entity implements INuclearEffect {
|
||||||
private boolean salted;
|
private boolean salted;
|
||||||
private boolean thermonuclear;
|
private boolean thermonuclear;
|
||||||
|
|
||||||
|
private ForgeChunkManager.Ticket ticket = null;
|
||||||
|
private boolean isChunkLoaded = false;
|
||||||
|
|
||||||
public EntityFalloutRain(World p_i1582_1_) {
|
public EntityFalloutRain(World p_i1582_1_) {
|
||||||
super(p_i1582_1_);
|
super(p_i1582_1_);
|
||||||
this.setSize(4, 20);
|
this.setSize(4, 20);
|
||||||
|
@ -106,7 +111,12 @@ public class EntityFalloutRain extends Entity implements INuclearEffect {
|
||||||
return bb;
|
return bb;
|
||||||
//return this.getEntityBoundingBox();
|
//return this.getEntityBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChunkTicket(ForgeChunkManager.Ticket ticket) {
|
||||||
|
this.ticket = ticket;
|
||||||
|
isChunkLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate() {
|
public void onUpdate() {
|
||||||
|
|
||||||
|
@ -156,7 +166,14 @@ public class EntityFalloutRain extends Entity implements INuclearEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(radProgress > getScale() * 2D) {
|
if(radProgress > getScale() * 2D) {
|
||||||
|
if(isChunkLoaded && !this.world.isRemote && ticket != null) {
|
||||||
|
int chunkX = (int)Math.floor(this.posX) >> 4;
|
||||||
|
int chunkZ = (int)Math.floor(this.posZ) >> 4;
|
||||||
|
// System.out.println(ticket + " being unloaded for " + chunkX + ", " + chunkZ);
|
||||||
|
ForgeChunkManager.unforceChunk(ticket, new ChunkPos(chunkX, chunkZ));
|
||||||
|
ForgeChunkManager.releaseTicket(ticket);
|
||||||
|
isChunkLoaded = false;
|
||||||
|
}
|
||||||
this.setDead();
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package trinity.entities;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
|
import trinity.Trinity;
|
||||||
import trinity.config.TrinityConfig;
|
import trinity.config.TrinityConfig;
|
||||||
import trinity.entities.EntityFalloutRain;
|
import trinity.entities.EntityFalloutRain;
|
||||||
//import trinity.explosion.ExplosionHyperspace;
|
//import trinity.explosion.ExplosionHyperspace;
|
||||||
|
@ -18,7 +19,9 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.ForgeChunkManager;
|
||||||
|
|
||||||
public class EntityNuclearExplosion extends Entity {
|
public class EntityNuclearExplosion extends Entity {
|
||||||
|
|
||||||
|
@ -35,7 +38,10 @@ public class EntityNuclearExplosion extends Entity {
|
||||||
public boolean thermal = true;
|
public boolean thermal = true;
|
||||||
public boolean Void = false;
|
public boolean Void = false;
|
||||||
public int chance = 0;
|
public int chance = 0;
|
||||||
|
|
||||||
|
private ForgeChunkManager.Ticket ticket = null;
|
||||||
|
private boolean isChunkLoaded = false;
|
||||||
|
|
||||||
ExplosionNukeRay explosion;
|
ExplosionNukeRay explosion;
|
||||||
|
|
||||||
public EntityNuclearExplosion(World p_i1582_1_) {
|
public EntityNuclearExplosion(World p_i1582_1_) {
|
||||||
|
@ -57,7 +63,18 @@ public class EntityNuclearExplosion extends Entity {
|
||||||
this.setDead();
|
this.setDead();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!isChunkLoaded && !this.world.isRemote) {
|
||||||
|
int chunkX = (int)Math.floor(this.posX) >> 4;
|
||||||
|
int chunkZ = (int)Math.floor(this.posZ) >> 4;
|
||||||
|
ticket = ForgeChunkManager.requestTicket(Trinity.instance, this.world, ForgeChunkManager.Type.NORMAL);
|
||||||
|
if(ticket != null) {
|
||||||
|
// System.out.println(ticket + " being loaded for " + chunkX + ", " + chunkZ);
|
||||||
|
ForgeChunkManager.forceChunk(ticket, new ChunkPos(chunkX, chunkZ));
|
||||||
|
isChunkLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BlockPos pos = new BlockPos(this.posX, this.posY, this.posZ);
|
BlockPos pos = new BlockPos(this.posX, this.posY, this.posZ);
|
||||||
this.world.playSound(this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LIGHTNING_THUNDER, SoundCategory.AMBIENT, 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F, false);
|
this.world.playSound(this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LIGHTNING_THUNDER, SoundCategory.AMBIENT, 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F, false);
|
||||||
|
|
||||||
|
@ -91,6 +108,7 @@ public class EntityNuclearExplosion extends Entity {
|
||||||
if(thermonuclear)
|
if(thermonuclear)
|
||||||
{
|
{
|
||||||
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
||||||
|
fallout.setChunkTicket(ticket);
|
||||||
fallout.posX = this.posX;
|
fallout.posX = this.posX;
|
||||||
fallout.posY = this.posY;
|
fallout.posY = this.posY;
|
||||||
fallout.posZ = this.posZ;
|
fallout.posZ = this.posZ;
|
||||||
|
@ -102,6 +120,7 @@ public class EntityNuclearExplosion extends Entity {
|
||||||
if(salted)
|
if(salted)
|
||||||
{
|
{
|
||||||
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
||||||
|
fallout.setChunkTicket(ticket);
|
||||||
fallout.posX = this.posX;
|
fallout.posX = this.posX;
|
||||||
fallout.posY = this.posY;
|
fallout.posY = this.posY;
|
||||||
fallout.posZ = this.posZ;
|
fallout.posZ = this.posZ;
|
||||||
|
@ -112,6 +131,7 @@ public class EntityNuclearExplosion extends Entity {
|
||||||
else if(!salted)
|
else if(!salted)
|
||||||
{
|
{
|
||||||
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
EntityFalloutRain fallout = new EntityFalloutRain(this.world);
|
||||||
|
fallout.setChunkTicket(ticket);
|
||||||
fallout.posX = this.posX;
|
fallout.posX = this.posX;
|
||||||
fallout.posY = this.posY;
|
fallout.posY = this.posY;
|
||||||
fallout.posZ = this.posZ;
|
fallout.posZ = this.posZ;
|
||||||
|
|
30
src/main/java/trinity/world/ChunkLoader.java
Normal file
30
src/main/java/trinity/world/ChunkLoader.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package trinity.world;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import com.google.common.collect.ListMultimap;
|
||||||
|
import net.minecraftforge.common.ForgeChunkManager;
|
||||||
|
|
||||||
|
|
||||||
|
public class ChunkLoader implements ForgeChunkManager.PlayerOrderedLoadingCallback {
|
||||||
|
private static ChunkLoader INSTANCE;
|
||||||
|
|
||||||
|
public static ChunkLoader getInstance() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new ChunkLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListMultimap<String, ForgeChunkManager.Ticket> playerTicketsLoaded(ListMultimap<String, ForgeChunkManager.Ticket> tickets, World world) {
|
||||||
|
return tickets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ticketsLoaded(List<ForgeChunkManager.Ticket> tickets, World world) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue