From 3e864bc43d61d9ea9aef89606b1d5b4037bce5e8 Mon Sep 17 00:00:00 2001 From: Pascal Date: Sat, 21 Dec 2024 20:10:30 +0100 Subject: [PATCH] Fix cascade chunkloading (#8) --- .../tileentity/TileEntityGrowLight.java | 13 +- .../tileentity/TileEntityMetaFloodlight.java | 112 ++++++------------ .../tileentity/TileEntityPhantomLight.java | 6 +- .../tileentity/TileEntitySmallFloodlight.java | 13 +- 4 files changed, 43 insertions(+), 101 deletions(-) diff --git a/src/main/java/de/keridos/floodlights/tileentity/TileEntityGrowLight.java b/src/main/java/de/keridos/floodlights/tileentity/TileEntityGrowLight.java index 423beef..08b0579 100644 --- a/src/main/java/de/keridos/floodlights/tileentity/TileEntityGrowLight.java +++ b/src/main/java/de/keridos/floodlights/tileentity/TileEntityGrowLight.java @@ -13,7 +13,6 @@ import cofh.api.energy.IEnergyContainerItem; import de.keridos.floodlights.compatability.ModCompatibility; import de.keridos.floodlights.handler.ConfigHandler; -import de.keridos.floodlights.init.ModBlocks; import de.keridos.floodlights.reference.Names; import de.keridos.floodlights.util.BlockPos; import de.keridos.floodlights.util.GeneralUtil; @@ -39,17 +38,7 @@ public void growSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } + setLightChecked(x, y, z, remove); } public void updateEntity() { diff --git a/src/main/java/de/keridos/floodlights/tileentity/TileEntityMetaFloodlight.java b/src/main/java/de/keridos/floodlights/tileentity/TileEntityMetaFloodlight.java index 865240d..13d5559 100644 --- a/src/main/java/de/keridos/floodlights/tileentity/TileEntityMetaFloodlight.java +++ b/src/main/java/de/keridos/floodlights/tileentity/TileEntityMetaFloodlight.java @@ -7,7 +7,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import net.minecraft.tileentity.TileEntity; import de.keridos.floodlights.handler.ConfigHandler; import de.keridos.floodlights.init.ModBlocks; @@ -56,19 +55,18 @@ public void toggleUpdateRun() { } public void setLight(int x, int y, int z) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockUVLightBlock) { + // Ensure we don't get or change a block which chunk hasn't been loaded yet to prevent cascade chunkloading + // and support `WorldServer.loadChunkOnRequest = false`. + if (!worldObj.blockExists(x, y, z) || worldObj.getBlock(x, y, z) == ModBlocks.blockUVLightBlock) { return; } if (worldObj.setBlock(x, y, z, ModBlocks.blockPhantomLight)) { - TileEntity tile = worldObj.getTileEntity(x, y, z); - if (tile instanceof TileEntityPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) tile; - light.addSource(this.xCoord, this.yCoord, this.zCoord); - worldObj.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - } - return; + TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); + light.addSource(this.xCoord, this.yCoord, this.zCoord); + worldObj.markBlockRangeForRenderUpdate(x, y, z, x, y, z); + } else { + this.toggleUpdateRun(); } - this.toggleUpdateRun(); } @Override @@ -204,17 +202,7 @@ public void straightSource(boolean remove) { int x = this.xCoord + this.orientation.offsetX * i; int y = this.yCoord + this.orientation.offsetY * i; int z = this.zCoord + this.orientation.offsetZ * i; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { break; } } @@ -267,17 +255,7 @@ public void wideConeSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { if (i < 4) { // This is for canceling the long rangs beams failedBeams[j] = true; } @@ -322,17 +300,7 @@ public void wideConeSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { break; } } @@ -350,17 +318,7 @@ public void narrowConeSource(boolean remove) { int x = this.xCoord + this.orientation.offsetX; int y = this.yCoord + this.orientation.offsetY; int z = this.zCoord + this.orientation.offsetZ; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { return; } } @@ -402,17 +360,7 @@ public void narrowConeSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { if (i < 8) { // This is for canceling the long rangs beams failedBeams[j] = true; } @@ -458,21 +406,33 @@ public void narrowConeSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + if (!setLightChecked(x, y, z, remove)) { break; } } } } } + + protected boolean setLightChecked(int x, int y, int z, boolean remove) { + if (!worldObj.blockExists(x, y, z)) { + return false; + } + + if (remove) { + if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { + TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); + light.removeSource(this.xCoord, this.yCoord, this.zCoord); + } + } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { + setLight(x, y, z); + } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { + TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); + light.addSource(this.xCoord, this.yCoord, this.zCoord); + } else if (worldObj.getBlock(x, y, z).isOpaqueCube()) { + return false; + } + + return true; + } } diff --git a/src/main/java/de/keridos/floodlights/tileentity/TileEntityPhantomLight.java b/src/main/java/de/keridos/floodlights/tileentity/TileEntityPhantomLight.java index aa045d8..41925e7 100644 --- a/src/main/java/de/keridos/floodlights/tileentity/TileEntityPhantomLight.java +++ b/src/main/java/de/keridos/floodlights/tileentity/TileEntityPhantomLight.java @@ -51,7 +51,11 @@ public void removeSource(int x, int y, int z) { } public void updateAllSources() { - for (int[] source : sources) { + // Create a local copy as we remove sources while iterating them. + // Not best-practive but better then changing public facing methods. + ArrayList sourcesCopy = new ArrayList<>(sources); + + for (int[] source : sourcesCopy) { TileEntity te = worldObj.getTileEntity(source[0], source[1], source[2]); if (te != null && te instanceof TileEntityMetaFloodlight) { ((TileEntityMetaFloodlight) te).toggleUpdateRun(); diff --git a/src/main/java/de/keridos/floodlights/tileentity/TileEntitySmallFloodlight.java b/src/main/java/de/keridos/floodlights/tileentity/TileEntitySmallFloodlight.java index c76d396..8a841c4 100644 --- a/src/main/java/de/keridos/floodlights/tileentity/TileEntitySmallFloodlight.java +++ b/src/main/java/de/keridos/floodlights/tileentity/TileEntitySmallFloodlight.java @@ -9,7 +9,6 @@ import cofh.api.energy.IEnergyContainerItem; import de.keridos.floodlights.compatability.ModCompatibility; import de.keridos.floodlights.handler.ConfigHandler; -import de.keridos.floodlights.init.ModBlocks; import de.keridos.floodlights.reference.Names; import de.keridos.floodlights.util.MathUtil; import ic2.api.item.ElectricItem; @@ -84,17 +83,7 @@ public void smallSource(boolean remove) { int x = this.xCoord + rotatedCoords[0]; int y = this.yCoord + rotatedCoords[1]; int z = this.zCoord + rotatedCoords[2]; - if (remove) { - if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.removeSource(this.xCoord, this.yCoord, this.zCoord); - } - } else if (worldObj.getBlock(x, y, z).isAir(worldObj, x, y, z)) { - setLight(x, y, z); - } else if (worldObj.getBlock(x, y, z) == ModBlocks.blockPhantomLight) { - TileEntityPhantomLight light = (TileEntityPhantomLight) worldObj.getTileEntity(x, y, z); - light.addSource(this.xCoord, this.yCoord, this.zCoord); - } + setLightChecked(x, y, z, remove); } }