From 10002e0c41ee3521512500da3a19203cd9abfdd0 Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 16 Jun 2024 19:39:59 +0200 Subject: [PATCH] PRISM complete --- changelog | 15 ++++ .../java/com/hbm/config/RadiationConfig.java | 6 ++ .../radiation/ChunkRadiationHandlerPRISM.java | 78 ++++++++++++++---- .../radiation/ChunkRadiationManager.java | 2 +- .../ContainerMachineSolderingStation.java | 3 +- .../java/com/hbm/main/ModEventHandler.java | 45 ++++++++++ .../{tank_HOTBLOOD.png => tank_BLOOD_HOT.png} | Bin 7 files changed, 131 insertions(+), 18 deletions(-) rename src/main/resources/assets/hbm/textures/models/tank/{tank_HOTBLOOD.png => tank_BLOOD_HOT.png} (100%) diff --git a/changelog b/changelog index 853a298c4..6eceec130 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,21 @@ +## Added +* PRISM + * A new 3D radiation system which makes use of block explosion resistance to determine spreading + * Unlike the 1.12.2 "pocket" system, radiation isn't perfectly sealed, blocks in a 16x16x16 area are simply summed up and used as a divisor + * Using enough high-resistance blocks (or a ton of lesser resistant blocks), radiation can still be effectively blocked (either thick concrete walls or a mountain) + * Radiation is still (sub) chunk based, so the radiation on both sides of a wall in the middle of a chunk will still be the same, the wall will however affect spreading to neighboring chunks + * For TPT players: radiation can be compared to pressure, where pressure also uses 4x4 pixel regions and is affected by pixels within those regions + ## Changed * Centrifuges and refineries now use analog circuits +* Updated the cyclotron, the GUI is now much cleaner and it uses water as coolant (produces LPS) instead of regular coolant +* Due to some people's inability to put a square peg into a square hole rather than a round one, it is now impossible to manually click soldering station ingredients into the wrong slot (you could have just shift-clicked, you know?) ## Fixed * Fixed hopper IO ignoring the stack limit on arc furnaces under certain circumstances * Fixed the watz powerplant not dropping as many HSS bolts as it should +* Fixed grates crashing servers when placed using shift click onto blocks +* Many machines now use the much more efficient byte buffer for sending information to the client which heavily reduces lag (NBT packing is a major contributor to TPS lg) +* Fixed issue where the power system would constantly disconnect when multiple dimensions are loaded +* Fixed the rare sideways-rendering tank not using the correct UV +* Fixed incorrect resource path for the hot blood tank, causing a missing texture diff --git a/src/main/java/com/hbm/config/RadiationConfig.java b/src/main/java/com/hbm/config/RadiationConfig.java index 83cf7a10d..0129c534f 100644 --- a/src/main/java/com/hbm/config/RadiationConfig.java +++ b/src/main/java/com/hbm/config/RadiationConfig.java @@ -1,5 +1,8 @@ package com.hbm.config; +import com.hbm.handler.radiation.ChunkRadiationHandlerPRISM; +import com.hbm.handler.radiation.ChunkRadiationManager; + import net.minecraftforge.common.config.Configuration; public class RadiationConfig { @@ -14,6 +17,7 @@ public class RadiationConfig { public static boolean enableContamination = true; public static boolean enableChunkRads = true; + public static boolean enablePRISM = false; public static boolean disableAsbestos = false; public static boolean disableCoal = false; @@ -47,6 +51,8 @@ public class RadiationConfig { enableContamination = CommonConfig.createConfigBool(config, CATEGORY_NUKE, "RADIATION_00_enableContamination", "Toggles player contamination (and negative effects from radiation poisoning)", true); enableChunkRads = CommonConfig.createConfigBool(config, CATEGORY_NUKE, "RADIATION_01_enableChunkRads", "Toggles the world radiation system (chunk radiation only, some blocks use an AoE!)", true); + enablePRISM = CommonConfig.createConfigBool(config, CATEGORY_NUKE, "RADIATION_99_enablePRISM", "Enables the new 3D resistance-aware PRISM radiation system", false); + if(enablePRISM) ChunkRadiationManager.proxy = new ChunkRadiationHandlerPRISM(); fogCh = CommonConfig.setDef(fogCh, 20); diff --git a/src/main/java/com/hbm/handler/radiation/ChunkRadiationHandlerPRISM.java b/src/main/java/com/hbm/handler/radiation/ChunkRadiationHandlerPRISM.java index 96a1bc9fa..9f6910472 100644 --- a/src/main/java/com/hbm/handler/radiation/ChunkRadiationHandlerPRISM.java +++ b/src/main/java/com/hbm/handler/radiation/ChunkRadiationHandlerPRISM.java @@ -42,7 +42,8 @@ import net.minecraftforge.event.world.WorldEvent; */ public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler { - private HashMap perWorld = new HashMap(); + public HashMap perWorld = new HashMap(); + public static int cycles = 0; public static final float MAX_RADIATION = 1_000_000; private static final String NBT_KEY_CHUNK_RADIATION = "hfr_prism_radiation_"; @@ -169,15 +170,53 @@ public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler { @Override public void updateSystem() { + cycles++; + for(Entry entries : perWorld.entrySet()) { World world = entries.getKey(); RadPerWorld system = entries.getValue(); + int rebuildAllowance = 25; + //it would be way to expensive to replace the sub-chunks entirely like with the old system //(that only used floats anyway...) so instead we shift the radiation into the prev value - for(Entry chunk : system.radiation.entrySet()) for(SubChunk sub : chunk.getValue()) if(sub != null) { - sub.prevRadiation = sub.radiation; - sub.radiation = 0; + for(Entry chunk : system.radiation.entrySet()) { + for(int i = 0; i < 16; i++) { + + SubChunk sub = chunk.getValue()[i]; + + boolean hasTriedRebuild = false; + + if(sub != null) { + sub.prevRadiation = sub.radiation; + sub.radiation = 0; + + //process some chunks that need extra rebuilding + if(rebuildAllowance > 0 && sub.needsRebuild) { + sub.rebuild(world, chunk.getKey().chunkXPos << 4, i << 4, chunk.getKey().chunkZPos << 4); + if(!sub.needsRebuild) { + rebuildAllowance--; + hasTriedRebuild = true; + } + } + + if(!hasTriedRebuild && Math.abs(chunk.getKey().chunkXPos * chunk.getKey().chunkZPos) % 5 == cycles % 5 && world.getChunkProvider().chunkExists(chunk.getKey().chunkXPos, chunk.getKey().chunkZPos)) { + + Chunk c = world.getChunkFromChunkCoords(chunk.getKey().chunkXPos, chunk.getKey().chunkZPos); + ExtendedBlockStorage[] xbs = c.getBlockStorageArray(); + ExtendedBlockStorage subChunk = xbs[i]; + int checksum = 0; + + if(subChunk != null) { + for(int iX = 0; iX < 16; iX++) for(int iY = 0; iY < 16; iY ++) for(int iZ = 0; iZ < 16; iZ ++) checksum += subChunk.getBlockLSBArray()[MathHelper.clamp_int(iY << 8 | iZ << 4 | iX, 0, 4095)]; + } + + if(checksum != sub.checksum) { + sub.rebuild(world, chunk.getKey().chunkXPos << 4, i << 4, chunk.getKey().chunkZPos << 4); + } + } + } + } } //has to support additions while iterating @@ -190,10 +229,12 @@ public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler { SubChunk sub = chunk.getValue()[i]; if(sub != null) { - if(sub.prevRadiation <= 0 || Float.isNaN(sub.prevRadiation)) continue; + if(sub.prevRadiation <= 0 || Float.isNaN(sub.prevRadiation) || Float.isInfinite(sub.prevRadiation)) continue; float radSpread = 0; for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) radSpread += spreadRadiation(world, sub, i, chunk.getKey(), chunk.getValue(), system.radiation, dir); sub.radiation += (sub.prevRadiation - radSpread) * 0.95F; + sub.radiation -= 1F; + sub.radiation = MathHelper.clamp_float(sub.radiation, 0, MAX_RADIATION); } } } @@ -262,8 +303,9 @@ public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler { public float[] yResist = new float[16]; public float[] zResist = new float[16]; public boolean needsRebuild = false; + public int checksum = 0; - public void updateBlock(World world, int x, int y, int z) { + @Deprecated public void updateBlock(World world, int x, int y, int z) { int cX = x >> 4; int cY = MathHelper.clamp_int(y >> 4, 0, 15); int cZ = z >> 4; @@ -319,17 +361,21 @@ public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler { Chunk chunk = world.getChunkFromChunkCoords(cX, cZ); ExtendedBlockStorage[] xbs = chunk.getBlockStorageArray(); ExtendedBlockStorage subChunk = xbs[cY]; + checksum = 0; - for(int iX = 0; iX < 16; iX++) { - for(int iY = 0; iY < 16; iY ++) { - for(int iZ = 0; iZ < 16; iZ ++) { - - Block b = subChunk.getBlockByExtId(iX, iY, iZ); - if(b.getMaterial() == Material.air) continue; - float resistance = b.getExplosionResistance(null, world, tX + iX, tY + iY, tZ + iZ, x, y, z); - xResist[iX] += resistance; - yResist[iY] += resistance; - zResist[iZ] += resistance; + if(subChunk != null) { + for(int iX = 0; iX < 16; iX++) { + for(int iY = 0; iY < 16; iY ++) { + for(int iZ = 0; iZ < 16; iZ ++) { + + Block b = subChunk.getBlockByExtId(iX, iY, iZ); + if(b.getMaterial() == Material.air) continue; + float resistance = b.getExplosionResistance(null, world, tX + iX, tY + iY, tZ + iZ, x, y, z); + xResist[iX] += resistance; + yResist[iY] += resistance; + zResist[iZ] += resistance; + checksum += subChunk.getBlockLSBArray()[MathHelper.clamp_int(iY << 8 | iZ << 4 | iX, 0, 4095)]; // the "good enough" approach + } } } } diff --git a/src/main/java/com/hbm/handler/radiation/ChunkRadiationManager.java b/src/main/java/com/hbm/handler/radiation/ChunkRadiationManager.java index 1c5c8121c..9cc989370 100644 --- a/src/main/java/com/hbm/handler/radiation/ChunkRadiationManager.java +++ b/src/main/java/com/hbm/handler/radiation/ChunkRadiationManager.java @@ -12,7 +12,7 @@ import net.minecraftforge.event.world.WorldEvent; public class ChunkRadiationManager { - public static ChunkRadiationHandler proxy = /*new ChunkRadiationHandlerNT();*/ new ChunkRadiationHandlerSimple(); /*new ChunkRadiationHandlerPRISM();*/ + public static ChunkRadiationHandler proxy = new ChunkRadiationHandlerSimple(); @SubscribeEvent public void onWorldLoad(WorldEvent.Load event) { diff --git a/src/main/java/com/hbm/inventory/container/ContainerMachineSolderingStation.java b/src/main/java/com/hbm/inventory/container/ContainerMachineSolderingStation.java index abb9cba02..d1ce587b2 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerMachineSolderingStation.java +++ b/src/main/java/com/hbm/inventory/container/ContainerMachineSolderingStation.java @@ -2,6 +2,7 @@ package com.hbm.inventory.container; import com.hbm.inventory.RecipesCommon.AStack; import com.hbm.inventory.SlotCraftingOutput; +import com.hbm.inventory.SlotNonRetarded; import com.hbm.inventory.SlotUpgrade; import com.hbm.inventory.recipes.SolderingRecipes; import com.hbm.items.ModItems; @@ -24,7 +25,7 @@ public class ContainerMachineSolderingStation extends Container { solderer = tile; //Inputs - for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) this.addSlotToContainer(new Slot(tile, i * 3 + j, 17 + j * 18, 18 + i * 18)); + for(int i = 0; i < 2; i++) for(int j = 0; j < 3; j++) this.addSlotToContainer(new SlotNonRetarded(tile, i * 3 + j, 17 + j * 18, 18 + i * 18)); //Output this.addSlotToContainer(new SlotCraftingOutput(playerInv.player, tile, 6, 107, 27)); //Battery diff --git a/src/main/java/com/hbm/main/ModEventHandler.java b/src/main/java/com/hbm/main/ModEventHandler.java index 1ceb0ada5..572aeb47d 100644 --- a/src/main/java/com/hbm/main/ModEventHandler.java +++ b/src/main/java/com/hbm/main/ModEventHandler.java @@ -6,6 +6,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Random; import org.apache.commons.lang3.math.NumberUtils; @@ -40,6 +41,10 @@ import com.hbm.handler.HTTPHandler; import com.hbm.handler.HbmKeybinds.EnumKeybind; import com.hbm.handler.pollution.PollutionHandler; import com.hbm.handler.pollution.PollutionHandler.PollutionType; +import com.hbm.handler.radiation.ChunkRadiationHandlerPRISM; +import com.hbm.handler.radiation.ChunkRadiationHandlerPRISM.RadPerWorld; +import com.hbm.handler.radiation.ChunkRadiationHandlerPRISM.SubChunk; +import com.hbm.handler.radiation.ChunkRadiationManager; import com.hbm.items.IEquipReceiver; import com.hbm.items.ModItems; import com.hbm.items.armor.ArmorFSB; @@ -118,6 +123,7 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.FoodStats; import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; +import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.ForgeDirection; @@ -1088,6 +1094,45 @@ public class ModEventHandler { player.worldObj.spawnParticle("townaura", player.posX + vec.xCoord, player.posY + 1 + vec.yCoord, player.posZ + vec.zCoord, 0.0, 0.0, 0.0); } } + + // PRISMDBG + /*if(!event.player.worldObj.isRemote) { + ChunkRadiationHandlerPRISM prism = (ChunkRadiationHandlerPRISM) ChunkRadiationManager.proxy; + + RadPerWorld perWorld = prism.perWorld.get(player.worldObj); + + if(perWorld != null) { + SubChunk[] chunk = perWorld.radiation.get(new ChunkCoordIntPair(((int) Math.floor(player.posX)) >> 4, ((int) Math.floor(player.posZ)) >> 4)); + + if(chunk != null) { + + int y = ((int) Math.floor(player.posY)) >> 4; + + if(y >= 0 && y <= 15) { + SubChunk sub = chunk[y]; + + if(sub != null) { + float xSum = 0, ySum = 0, zSum = 0; + for(int i = 0; i < 16; i++) { + xSum += sub.xResist[i]; ySum += sub.yResist[i]; zSum += sub.zResist[i]; + } + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "FREE SPACE", 1), (EntityPlayerMP) player); + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "FREE SPACE", 2), (EntityPlayerMP) player); + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.GREEN + "" + sub.checksum + " - " + ((int) sub.radiation) + "RAD/s - " + sub.needsRebuild + + " - " + (int) xSum+ " - " + (int) ySum + " - " + (int) zSum, 3), (EntityPlayerMP) player); + } else { + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "SUB IS NULL", 1), (EntityPlayerMP) player); + } + } else { + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "OUTSIDE OF WORLD", 1), (EntityPlayerMP) player); + } + } else { + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "CHUNK IS NULL", 1), (EntityPlayerMP) player); + } + } else { + PacketDispatcher.wrapper.sendTo(new PlayerInformPacket(EnumChatFormatting.RED + "PERWORLD IS NULL", 1), (EntityPlayerMP) player); + } + }*/ } @SubscribeEvent diff --git a/src/main/resources/assets/hbm/textures/models/tank/tank_HOTBLOOD.png b/src/main/resources/assets/hbm/textures/models/tank/tank_BLOOD_HOT.png similarity index 100% rename from src/main/resources/assets/hbm/textures/models/tank/tank_HOTBLOOD.png rename to src/main/resources/assets/hbm/textures/models/tank/tank_BLOOD_HOT.png