PRISM complete

This commit is contained in:
Bob 2024-06-16 19:39:59 +02:00
parent f9075c9247
commit 10002e0c41
7 changed files with 131 additions and 18 deletions

View File

@ -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

View File

@ -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);

View File

@ -42,7 +42,8 @@ import net.minecraftforge.event.world.WorldEvent;
*/
public class ChunkRadiationHandlerPRISM extends ChunkRadiationHandler {
private HashMap<World, RadPerWorld> perWorld = new HashMap();
public HashMap<World, RadPerWorld> 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<World, RadPerWorld> 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<ChunkCoordIntPair, SubChunk[]> chunk : system.radiation.entrySet()) for(SubChunk sub : chunk.getValue()) if(sub != null) {
sub.prevRadiation = sub.radiation;
sub.radiation = 0;
for(Entry<ChunkCoordIntPair, SubChunk[]> 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
}
}
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB