mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
god have mercy
This commit is contained in:
parent
f3e0ad9cc2
commit
5867640c22
6
src/main/java/com/hbm/blocks/IRadResistantBlock.java
Normal file
6
src/main/java/com/hbm/blocks/IRadResistantBlock.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.hbm.blocks;
|
||||
|
||||
public interface IRadResistantBlock {
|
||||
|
||||
public int getResistance();
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.hbm.handler.radiation;
|
||||
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
@ -22,6 +23,7 @@ public abstract class ChunkRadiationHandler {
|
||||
*/
|
||||
public void receiveWorldLoad(WorldEvent.Load event) { }
|
||||
public void receiveWorldUnload(WorldEvent.Unload event) { }
|
||||
public void receiveWorldTick(TickEvent.ServerTickEvent event) { }
|
||||
|
||||
public void receiveChunkLoad(ChunkDataEvent.Load event) { }
|
||||
public void receiveChunkSave(ChunkDataEvent.Save event) { }
|
||||
|
||||
@ -1,36 +1,621 @@
|
||||
package com.hbm.handler.radiation;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hbm.blocks.IRadResistantBlock;
|
||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
/**
|
||||
* @author Drillgon200, hit with a hammer until it works in 1.7.10 by Bob
|
||||
*
|
||||
*/
|
||||
public class ChunkRadiationHandlerNT extends ChunkRadiationHandler {
|
||||
|
||||
@Override
|
||||
public float getRadiation(World world, int x, int y, int z) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRadiation(World world, int x, int y, int z, float rad) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* once i have to start debugging this, even my nightmares will start shitting themselves */
|
||||
|
||||
private static HashMap<World, WorldRadiationData> worldMap = new HashMap();
|
||||
|
||||
@Override
|
||||
public void incrementRad(World world, int x, int y, int z, float rad) {
|
||||
// TODO Auto-generated method stub
|
||||
if(!world.blockExists(x, y, z)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RadPocket p = getPocket(world, x, y, z);
|
||||
p.radiation += rad;
|
||||
|
||||
if(rad > 0){
|
||||
WorldRadiationData data = getWorldRadData(world);
|
||||
data.activePockets.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrementRad(World world, int x, int y, int z, float rad) {
|
||||
// TODO Auto-generated method stub
|
||||
if(y < 0 || y > 255 || !isSubChunkLoaded(world, x, y, z)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RadPocket p = getPocket(world, x, y, z);
|
||||
p.radiation -= Math.max(rad, 0);
|
||||
if(p.radiation < 0){
|
||||
p.radiation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRadiation(World world, int x, int y, int z, float rad) {
|
||||
RadPocket p = getPocket(world, x, y, z);
|
||||
p.radiation = Math.max(rad, 0);
|
||||
|
||||
if(rad > 0){
|
||||
WorldRadiationData data = getWorldRadData(world);
|
||||
data.activePockets.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRadiation(World world, int x, int y, int z) {
|
||||
if(!isSubChunkLoaded(world, x, y, z))
|
||||
return 0;
|
||||
return getPocket(world, x, y, z).radiation;
|
||||
}
|
||||
|
||||
public static void jettisonData(World world){
|
||||
WorldRadiationData data = getWorldRadData(world);
|
||||
data.data.clear();
|
||||
data.activePockets.clear();
|
||||
}
|
||||
|
||||
public static RadPocket getPocket(World world, int x, int y, int z){
|
||||
return getSubChunkStorage(world, x, y, z).getPocket(x, y, z);
|
||||
}
|
||||
|
||||
public static Collection<RadPocket> getActiveCollection(World world){
|
||||
return getWorldRadData(world).activePockets;
|
||||
}
|
||||
|
||||
public static boolean isSubChunkLoaded(World world, int x, int y, int z){
|
||||
|
||||
if(y < 0 || y > 255)
|
||||
return false;
|
||||
|
||||
WorldRadiationData worldRadData = worldMap.get(world);
|
||||
if(worldRadData == null){
|
||||
return false;
|
||||
}
|
||||
ChunkRadiationStorage st = worldRadData.data.get(new ChunkCoordIntPair(x >> 4, z >> 4)); // !!!
|
||||
if(st == null){
|
||||
return false;
|
||||
}
|
||||
SubChunkRadiationStorage sc = st.getForYLevel(y);
|
||||
if(sc == null){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SubChunkRadiationStorage getSubChunkStorage(World world, int x, int y, int z){
|
||||
ChunkRadiationStorage st = getChunkStorage(world, x, y, z);
|
||||
SubChunkRadiationStorage sc = st.getForYLevel(y);
|
||||
//If the sub chunk doesn't exist, bring it into existence by rebuilding the sub chunk, then get it.
|
||||
if(sc == null){
|
||||
rebuildChunkPockets(world.getChunkFromBlockCoords(x, z), y >> 4);
|
||||
}
|
||||
sc = st.getForYLevel(y);
|
||||
return sc;
|
||||
}
|
||||
|
||||
public static ChunkRadiationStorage getChunkStorage(World world, int x, int y, int z){
|
||||
WorldRadiationData worldRadData = getWorldRadData(world);
|
||||
ChunkRadiationStorage st = worldRadData.data.get(new ChunkCoordIntPair(x >> 4, z >> 4));
|
||||
//If it doesn't currently exist, create it
|
||||
if(st == null){
|
||||
st = new ChunkRadiationStorage(worldRadData, world.getChunkFromBlockCoords(x, z));
|
||||
worldRadData.data.put(new ChunkCoordIntPair(x >> 4,z >> 4), st);
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world radiation data for the world
|
||||
* @param world - the world to get the radiation data from
|
||||
* @return the radiation data for the world
|
||||
*/
|
||||
private static WorldRadiationData getWorldRadData(World world){
|
||||
WorldRadiationData worldRadData = worldMap.get(world);
|
||||
//If we don't have one, make a new one
|
||||
if(worldRadData == null){
|
||||
worldRadData = new WorldRadiationData(world);
|
||||
worldMap.put(world, worldRadData);
|
||||
}
|
||||
return worldRadData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSystem() {
|
||||
// TODO Auto-generated method stub
|
||||
updateRadiation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveWorldTick(TickEvent.ServerTickEvent event) {
|
||||
rebuildDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveChunkUnload(ChunkEvent.Unload event) {
|
||||
|
||||
if(!event.world.isRemote){
|
||||
|
||||
WorldRadiationData data = getWorldRadData(event.world);
|
||||
if(data.data.containsKey(event.getChunk().getChunkCoordIntPair())){
|
||||
data.data.get(event.getChunk().getChunkCoordIntPair()).unload();
|
||||
data.data.remove(event.getChunk().getChunkCoordIntPair());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveChunkLoad(ChunkDataEvent.Load event) {
|
||||
if(!event.world.isRemote){
|
||||
if(event.getData().hasKey("hbmRadDataNT")){
|
||||
WorldRadiationData data = getWorldRadData(event.world);
|
||||
ChunkRadiationStorage cData = new ChunkRadiationStorage(data, event.getChunk());
|
||||
cData.readFromNBT(event.getData().getCompoundTag("hbmRadDataNT"));
|
||||
data.data.put(event.getChunk().getChunkCoordIntPair(), cData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveChunkSave(ChunkDataEvent.Save event) {
|
||||
if(!event.world.isRemote){
|
||||
WorldRadiationData data = getWorldRadData(event.world);
|
||||
if(data.data.containsKey(event.getChunk().getChunkCoordIntPair())){
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
data.data.get(event.getChunk().getChunkCoordIntPair()).writeToNBT(tag);
|
||||
event.getData().setTag("hbmRadDataNT", tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveWorldLoad(WorldEvent.Load event){
|
||||
if(!event.world.isRemote){
|
||||
worldMap.put(event.world, new WorldRadiationData(event.world));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveWorldUnload(WorldEvent.Unload event){
|
||||
if(!event.world.isRemote){
|
||||
worldMap.remove(event.world);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateRadiation() {
|
||||
// TODO //
|
||||
}
|
||||
|
||||
public static void markChunkForRebuild(World world, int x, int y, int z){
|
||||
BlockPos chunkPos = new BlockPos(x >> 4, y >> 4, z >> 4);
|
||||
WorldRadiationData r = getWorldRadData(world);
|
||||
|
||||
if(r.iteratingDirty){
|
||||
r.dirtyChunks2.add(chunkPos);
|
||||
} else {
|
||||
r.dirtyChunks.add(chunkPos);
|
||||
}
|
||||
}
|
||||
|
||||
private static void rebuildDirty(){
|
||||
for(WorldRadiationData r : worldMap.values()){
|
||||
r.iteratingDirty = true;
|
||||
for(BlockPos b : r.dirtyChunks){
|
||||
rebuildChunkPockets(r.world.getChunkFromChunkCoords(b.getX(), b.getZ()), b.getY());
|
||||
}
|
||||
r.iteratingDirty = false;
|
||||
r.dirtyChunks.clear();
|
||||
r.dirtyChunks.addAll(r.dirtyChunks2);
|
||||
r.dirtyChunks2.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static RadPocket[] pocketsByBlock = null;
|
||||
|
||||
private static void rebuildChunkPockets(Chunk chunk, int yIndex){
|
||||
|
||||
BlockPos subChunkPos = new BlockPos(chunk.getChunkCoordIntPair().chunkXPos << 4, yIndex << 4, chunk.getChunkCoordIntPair().chunkZPos << 4);
|
||||
List<RadPocket> pockets = new ArrayList();
|
||||
ExtendedBlockStorage blocks = chunk.getBlockStorageArray()[yIndex];
|
||||
if(pocketsByBlock == null) {
|
||||
pocketsByBlock = new RadPocket[16*16*16];
|
||||
} else {
|
||||
Arrays.fill(pocketsByBlock, null);
|
||||
}
|
||||
ChunkRadiationStorage st = getChunkStorage(chunk.worldObj, subChunkPos.getX(), subChunkPos.getY(), subChunkPos.getZ());
|
||||
SubChunkRadiationStorage subChunk = new SubChunkRadiationStorage(st, subChunkPos.getY(), null, null);
|
||||
|
||||
if(blocks != null){
|
||||
for(int x = 0; x < 16; x ++){
|
||||
for(int y = 0; y < 16; y ++){
|
||||
for(int z = 0; z < 16; z ++){
|
||||
if(pocketsByBlock[x*16*16+y*16+z] != null)
|
||||
continue;
|
||||
Block block = blocks.getBlockByExtId(x, y, z); // !!!
|
||||
if(!(block instanceof IRadResistantBlock && ((IRadResistantBlock) block).getResistance() == 1)){
|
||||
pockets.add(buildPocket(subChunk, chunk.worldObj, new BlockPos(x, y, z), subChunkPos, blocks, pocketsByBlock, pockets.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RadPocket pocket = new RadPocket(subChunk, 0);
|
||||
for(int x = 0; x < 16; x ++){
|
||||
for(int y = 0; y < 16; y ++){
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(x, 0, y), pocket, ForgeDirection.DOWN);
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(x, 15, y), pocket, ForgeDirection.UP);
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(x, y, 0), pocket, ForgeDirection.NORTH);
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(x, y, 15), pocket, ForgeDirection.SOUTH);
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(0, y, x), pocket, ForgeDirection.WEST);
|
||||
doEmptyChunk(chunk, subChunkPos, new BlockPos(15, y, x), pocket, ForgeDirection.EAST);
|
||||
}
|
||||
}
|
||||
pockets.add(pocket);
|
||||
}
|
||||
subChunk.pocketsByBlock = pockets.size() == 1 ? null : pocketsByBlock;
|
||||
if(subChunk.pocketsByBlock != null)
|
||||
pocketsByBlock = null;
|
||||
subChunk.pockets = pockets.toArray(new RadPocket[pockets.size()]);
|
||||
st.setForYLevel(yIndex << 4, subChunk);
|
||||
}
|
||||
|
||||
private static void doEmptyChunk(Chunk chunk, BlockPos subChunkPos, BlockPos pos, RadPocket pocket, ForgeDirection facing){
|
||||
BlockPos newPos = pos.offset(facing);
|
||||
BlockPos outPos = newPos.add(subChunkPos);
|
||||
Block block = chunk.worldObj.getBlock(outPos.getX(), outPos.getY(), outPos.getZ());
|
||||
if(!(block instanceof IRadResistantBlock && ((IRadResistantBlock) block).getResistance() == 1)){
|
||||
if(!isSubChunkLoaded(chunk.worldObj, outPos.getX(), outPos.getY(), outPos.getZ())){
|
||||
if(!pocket.connectionIndices[facing.ordinal()].contains(-1)){
|
||||
pocket.connectionIndices[facing.ordinal()].add(-1);
|
||||
}
|
||||
} else {
|
||||
|
||||
RadPocket outPocket = getPocket(chunk.worldObj, outPos.getX(), outPos.getY(), outPos.getZ());
|
||||
if(!pocket.connectionIndices[facing.ordinal()].contains(Integer.valueOf(outPocket.index)))
|
||||
pocket.connectionIndices[facing.ordinal()].add(outPocket.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Queue<BlockPos> stack = new ArrayDeque(1024);
|
||||
|
||||
private static RadPocket buildPocket(SubChunkRadiationStorage subChunk, World world, BlockPos start, BlockPos subChunkWorldPos, ExtendedBlockStorage chunk, RadPocket[] pocketsByBlock, int index){
|
||||
RadPocket pocket = new RadPocket(subChunk, index);
|
||||
stack.clear();
|
||||
stack.add(start);
|
||||
while(!stack.isEmpty()){
|
||||
BlockPos pos = stack.poll();
|
||||
Block block = chunk.getBlockByExtId(pos.getX(), pos.getY(), pos.getZ()); // !!!
|
||||
if(pocketsByBlock[pos.getX()*16*16+pos.getY()*16+pos.getZ()] != null || (block instanceof IRadResistantBlock && ((IRadResistantBlock) block).getResistance() == 1)){
|
||||
continue;
|
||||
}
|
||||
pocketsByBlock[pos.getX()*16*16+pos.getY()*16+pos.getZ()] = pocket;
|
||||
for(ForgeDirection facing : ForgeDirection.VALID_DIRECTIONS){
|
||||
BlockPos newPos = pos.offset(facing);
|
||||
if(Math.max(Math.max(newPos.getX(), newPos.getY()), newPos.getZ()) > 15 || Math.min(Math.min(newPos.getX(), newPos.getY()), newPos.getZ()) < 0){
|
||||
BlockPos outPos = newPos.add(subChunkWorldPos);
|
||||
if(outPos.getY() < 0 || outPos.getY() > 255)
|
||||
continue;
|
||||
block = world.getBlock(outPos.getX(), outPos.getY(), outPos.getZ()); // !!!
|
||||
if(!(block instanceof IRadResistantBlock && ((IRadResistantBlock) block).getResistance() == 1)){
|
||||
if(!isSubChunkLoaded(world, outPos.getX(), outPos.getY(), outPos.getZ())){
|
||||
if(!pocket.connectionIndices[facing.ordinal()].contains(-1)){
|
||||
pocket.connectionIndices[facing.ordinal()].add(-1);
|
||||
}
|
||||
} else {
|
||||
RadPocket outPocket = getPocket(world, outPos.getX(), outPos.getY(), outPos.getZ());
|
||||
if(!pocket.connectionIndices[facing.ordinal()].contains(Integer.valueOf(outPocket.index)))
|
||||
pocket.connectionIndices[facing.ordinal()].add(outPocket.index);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
stack.add(newPos);
|
||||
}
|
||||
}
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public static class RadPocket {
|
||||
public SubChunkRadiationStorage parent;
|
||||
public int index;
|
||||
public float radiation;
|
||||
private float accumulatedRads = 0;
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Integer>[] connectionIndices = new List[ForgeDirection.VALID_DIRECTIONS.length];
|
||||
|
||||
public RadPocket(SubChunkRadiationStorage parent, int index) {
|
||||
this.parent = parent;
|
||||
this.index = index;
|
||||
for(int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i ++){
|
||||
connectionIndices[i] = new ArrayList<>(1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void remove(World world, BlockPos pos){
|
||||
for(ForgeDirection e : ForgeDirection.VALID_DIRECTIONS){
|
||||
connectionIndices[e.ordinal()].clear();
|
||||
}
|
||||
parent.parent.parent.activePockets.remove(this);
|
||||
}
|
||||
|
||||
public BlockPos getSubChunkPos() {
|
||||
return parent.parent.getWorldPos(parent.yLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SubChunkRadiationStorage {
|
||||
public ChunkRadiationStorage parent;
|
||||
public int yLevel;
|
||||
public RadPocket[] pocketsByBlock;
|
||||
public RadPocket[] pockets;
|
||||
|
||||
public SubChunkRadiationStorage(ChunkRadiationStorage parent, int yLevel, RadPocket[] pocketsByBlock, RadPocket[] pockets) {
|
||||
this.parent = parent;
|
||||
this.yLevel = yLevel;
|
||||
this.pocketsByBlock = pocketsByBlock;
|
||||
this.pockets = pockets;
|
||||
}
|
||||
|
||||
public RadPocket getPocket(int x, int y, int z){
|
||||
if(pocketsByBlock == null){
|
||||
return pockets[0];
|
||||
} else {
|
||||
x &= 15;
|
||||
y &= 15;
|
||||
z &= 15;
|
||||
|
||||
RadPocket p = pocketsByBlock[x * 16 * 16 + y *16 + z];
|
||||
return p == null ? pockets[0] : p;
|
||||
}
|
||||
}
|
||||
|
||||
public void setRad(SubChunkRadiationStorage other){
|
||||
float total = 0;
|
||||
for(RadPocket p : other.pockets){
|
||||
total += p.radiation;
|
||||
}
|
||||
float radPer = total/pockets.length;
|
||||
for(RadPocket p : pockets){
|
||||
p.radiation = radPer;
|
||||
if(radPer > 0){
|
||||
p.parent.parent.parent.activePockets.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(World world, BlockPos pos){
|
||||
for(RadPocket p : pockets){
|
||||
p.remove(world, pos);
|
||||
}
|
||||
for(ForgeDirection e : ForgeDirection.VALID_DIRECTIONS){
|
||||
//world.getBlockState(pos.offset(e, 16));
|
||||
|
||||
IChunkProvider provider = world.getChunkProvider();
|
||||
provider.loadChunk((pos.getX() + 16) >> 4, (pos.getZ() + 16) >> 4); // !!!
|
||||
|
||||
BlockPos offPos = pos.offset(e, 16);
|
||||
if(isSubChunkLoaded(world, offPos.getX(), offPos.getY(), offPos.getZ())){
|
||||
SubChunkRadiationStorage sc = getSubChunkStorage(world, offPos.getX(), offPos.getY(), offPos.getZ());
|
||||
for(RadPocket p : sc.pockets){
|
||||
p.connectionIndices[e.getOpposite().ordinal()].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(World world, BlockPos pos){
|
||||
for(ForgeDirection e : ForgeDirection.VALID_DIRECTIONS){
|
||||
//world.getBlockState(pos.offset(e, 16));
|
||||
|
||||
IChunkProvider provider = world.getChunkProvider();
|
||||
provider.loadChunk((pos.getX() + 16) >> 4, (pos.getZ() + 16) >> 4); // !!!
|
||||
|
||||
BlockPos offPos = pos.offset(e, 16);
|
||||
if(isSubChunkLoaded(world, offPos.getX(), offPos.getY(), offPos.getZ())){
|
||||
SubChunkRadiationStorage sc = getSubChunkStorage(world, offPos.getX(), offPos.getY(), offPos.getZ());
|
||||
for(RadPocket p : sc.pockets){
|
||||
p.connectionIndices[e.getOpposite().ordinal()].clear();
|
||||
}
|
||||
for(RadPocket p : pockets){
|
||||
List<Integer> indc = p.connectionIndices[e.ordinal()];
|
||||
for(int idx : indc){
|
||||
sc.pockets[idx].connectionIndices[e.getOpposite().ordinal()].add(p.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ChunkRadiationStorage {
|
||||
private static ByteBuffer buf = ByteBuffer.allocate(524288);
|
||||
|
||||
public WorldRadiationData parent;
|
||||
private Chunk chunk;
|
||||
private SubChunkRadiationStorage[] chunks = new SubChunkRadiationStorage[16];
|
||||
|
||||
public ChunkRadiationStorage(WorldRadiationData parent, Chunk chunk) {
|
||||
this.parent = parent;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
public SubChunkRadiationStorage getForYLevel(int y){
|
||||
int idx = y >> 4;
|
||||
if(idx < 0 || idx > chunks.length){
|
||||
return null;
|
||||
}
|
||||
return chunks[y >> 4];
|
||||
}
|
||||
|
||||
public BlockPos getWorldPos(int y){
|
||||
return new BlockPos(chunk.getChunkCoordIntPair().chunkXPos << 4, y, chunk.getChunkCoordIntPair().chunkZPos << 4);
|
||||
}
|
||||
|
||||
public void setForYLevel(int y, SubChunkRadiationStorage sc){
|
||||
if(chunks[y >> 4] != null){
|
||||
chunks[y >> 4].remove(chunk.worldObj, getWorldPos(y));
|
||||
if(sc != null)
|
||||
sc.setRad(chunks[y >> 4]);
|
||||
}
|
||||
if(sc != null){
|
||||
sc.add(chunk.worldObj, getWorldPos(y));
|
||||
}
|
||||
chunks[y >> 4] = sc;
|
||||
}
|
||||
|
||||
public void unload(){
|
||||
for(int y = 0; y < chunks.length; y ++){
|
||||
if(chunks[y] == null)
|
||||
continue;
|
||||
for(RadPocket p : chunks[y].pockets){
|
||||
parent.activePockets.remove(p);
|
||||
}
|
||||
chunks[y] = null;
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag){
|
||||
for(SubChunkRadiationStorage st : chunks){
|
||||
if(st == null){
|
||||
buf.put((byte) 0);
|
||||
} else {
|
||||
buf.put((byte) 1);
|
||||
buf.putShort((short) st.yLevel);
|
||||
buf.putShort((short)st.pockets.length);
|
||||
for(RadPocket p : st.pockets){
|
||||
writePocket(buf, p);
|
||||
}
|
||||
if(st.pocketsByBlock == null){
|
||||
buf.put((byte) 0);
|
||||
} else {
|
||||
buf.put((byte) 1);
|
||||
for(RadPocket p : st.pocketsByBlock){
|
||||
buf.putShort(arrayIndex(p, st.pockets));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.flip();
|
||||
byte[] data = new byte[buf.limit()];
|
||||
buf.get(data);
|
||||
tag.setByteArray("chunkRadData", data);
|
||||
buf.clear();
|
||||
return tag;
|
||||
}
|
||||
|
||||
public short arrayIndex(RadPocket p, RadPocket[] pockets){
|
||||
for(short i = 0; i < pockets.length; i ++){
|
||||
if(p == pockets[i])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void writePocket(ByteBuffer buf, RadPocket p){
|
||||
buf.putInt(p.index);
|
||||
buf.putFloat(p.radiation);
|
||||
for(ForgeDirection e : ForgeDirection.VALID_DIRECTIONS){
|
||||
List<Integer> indc = p.connectionIndices[e.ordinal()];
|
||||
buf.putShort((short) indc.size());
|
||||
for(int idx : indc){
|
||||
buf.putShort((short) idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound tag){
|
||||
ByteBuffer data = ByteBuffer.wrap(tag.getByteArray("chunkRadData"));
|
||||
for(int i = 0; i < chunks.length; i ++){
|
||||
boolean subChunkExists = data.get() == 1 ? true : false;
|
||||
if(subChunkExists){
|
||||
int yLevel = data.getShort();
|
||||
SubChunkRadiationStorage st = new SubChunkRadiationStorage(this, yLevel, null, null);
|
||||
int pocketsLength = data.getShort();
|
||||
st.pockets = new RadPocket[pocketsLength];
|
||||
for(int j = 0; j < pocketsLength; j ++){
|
||||
st.pockets[j] = readPocket(data, st);
|
||||
if(st.pockets[j].radiation > 0){
|
||||
parent.activePockets.add(st.pockets[j]);
|
||||
}
|
||||
}
|
||||
boolean perBlockDataExists = data.get() == 1 ? true : false;
|
||||
if(perBlockDataExists){
|
||||
st.pocketsByBlock = new RadPocket[16*16*16];
|
||||
for(int j = 0; j < 16*16*16; j ++){
|
||||
int idx = data.getShort();
|
||||
if(idx >= 0)
|
||||
st.pocketsByBlock[j] = st.pockets[idx];
|
||||
}
|
||||
}
|
||||
chunks[i] = st;
|
||||
} else {
|
||||
chunks[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RadPocket readPocket(ByteBuffer buf, SubChunkRadiationStorage parent){
|
||||
int index = buf.getInt();
|
||||
RadPocket p = new RadPocket(parent, index);
|
||||
p.radiation = buf.getFloat();
|
||||
for(ForgeDirection e : ForgeDirection.VALID_DIRECTIONS){
|
||||
List<Integer> indc = p.connectionIndices[e.ordinal()];
|
||||
int size = buf.getShort();
|
||||
for(int i = 0; i < size; i ++){
|
||||
indc.add((int) buf.getShort());
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WorldRadiationData {
|
||||
public World world;
|
||||
private Set<BlockPos> dirtyChunks = new HashSet();
|
||||
private Set<BlockPos> dirtyChunks2 = new HashSet();
|
||||
private boolean iteratingDirty = false;
|
||||
|
||||
public Set<RadPocket> activePockets = new HashSet();
|
||||
public HashMap<ChunkCoordIntPair, ChunkRadiationStorage> data = new HashMap();
|
||||
|
||||
public WorldRadiationData(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,6 +56,8 @@ public class ChunkRadiationManager {
|
||||
if(RadiationConfig.worldRadEffects) {
|
||||
proxy.handleWorldDestruction();
|
||||
}
|
||||
|
||||
proxy.receiveWorldTick(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.hbm.util.fauxpointtwelve;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
/**
|
||||
* Adjusted code from MC 1.12 (com.minecraft.util.math.BlockPos)
|
||||
@ -47,6 +48,14 @@ public class BlockPos {
|
||||
case COUNTERCLOCKWISE_90: return new BlockPos(this.getZ(), this.getY(), -this.getX());
|
||||
}
|
||||
}
|
||||
|
||||
public BlockPos offset(ForgeDirection dir) {
|
||||
return this.offset(dir, 1);
|
||||
}
|
||||
|
||||
public BlockPos offset(ForgeDirection dir, int distance) {
|
||||
return new BlockPos(x + dir.offsetX * distance, y + dir.offsetY * distance, z + dir.offsetZ * distance);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
@ -60,31 +69,27 @@ public class BlockPos {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
/** 1.12 vanilla implementation */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
result = prime * result + z;
|
||||
return result;
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(this == obj)
|
||||
public boolean equals(Object toCompare) {
|
||||
if(this == toCompare) {
|
||||
return true;
|
||||
if(obj == null)
|
||||
} else if(!(toCompare instanceof BlockPos)) {
|
||||
return false;
|
||||
if(getClass() != obj.getClass())
|
||||
return false;
|
||||
BlockPos other = (BlockPos) obj;
|
||||
if(x != other.x)
|
||||
return false;
|
||||
if(y != other.y)
|
||||
return false;
|
||||
if(z != other.z)
|
||||
return false;
|
||||
return true;
|
||||
} else {
|
||||
BlockPos pos = (BlockPos) toCompare;
|
||||
if(this.getX() != pos.getX()) {
|
||||
return false;
|
||||
} else if(this.getY() != pos.getY()) {
|
||||
return false;
|
||||
} else {
|
||||
return this.getZ() == pos.getZ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user