package mcjty.deepresonance.radiation;
import com.google.common.collect.Maps;
import elec332.core.world.WorldHelper;
import mcjty.deepresonance.varia.QuadTree;
import mcjty.lib.varia.GlobalCoordinate;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import net.minecraftforge.common.util.Constants;
import java.util.Map;
public class DRRadiationManager extends WorldSavedData {
public static final String RADIATION_MANAGER_NAME = "DRRadiationManager";
private static DRRadiationManager instance = null;
private final Map<GlobalCoordinate, RadiationSource> sources = Maps.newHashMap();
public DRRadiationManager(String identifier) {
super(identifier);
}
public static float calculateRadiationStrength(float strength, float purity) {
float p = (float) Math.log10(purity / 100.0f) + 1.0f;
if (p < 0.01f) {
p = 0.01f;
}
float str = RadiationConfiguration.minRadiationStrength + strength * (1.0f - p) / 100.0f
* (RadiationConfiguration.maxRadiationStrength - RadiationConfiguration.minRadiationStrength);
return str;
}
public static float calculateRadiationRadius(float strength, float efficiency, float purity) {
float radius = RadiationConfiguration.minRadiationRadius + (strength + efficiency) / 200.0f
* (RadiationConfiguration.maxRadiationRadius - RadiationConfiguration.minRadiationRadius);
radius += radius * (100.0f - purity) * .002f;
return radius;
}
public void save(World world) {
world.setItemData(RADIATION_MANAGER_NAME, this);
markDirty();
}
public static void clearInstance() {
if (instance != null) {
instance.sources.clear();
instance = null;
}
}
public void removeAllRadiation() {
sources.clear();
}
public static DRRadiationManager getManager() {
return instance;
}
public static DRRadiationManager getManager(World world) {
if (world.isRemote) {
return null;
}
if (instance != null) {
return instance;
}
instance = (DRRadiationManager) world.loadItemData(DRRadiationManager.class, RADIATION_MANAGER_NAME);
if (instance == null) {
instance = new DRRadiationManager(RADIATION_MANAGER_NAME);
}
return instance;
}
public RadiationSource getOrCreateRadiationSource(GlobalCoordinate coordinate) {
RadiationSource source = sources.get(coordinate);
if (source == null) {
source = new RadiationSource();
sources.put(coordinate, source);
}
return source;
}
public RadiationSource getRadiationSource(GlobalCoordinate coordinate) {
return sources.get(coordinate);
}
public Map<GlobalCoordinate, RadiationSource> getRadiationSources() {
return sources;
}
public void deleteRadiationSource(GlobalCoordinate coordinate) {
sources.remove(coordinate);
}
@Override
public void readFromNBT(NBTTagCompound tagCompound) {
sources.clear();
NBTTagList lst = tagCompound.getTagList("radiation", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < lst.tagCount(); i++) {
NBTTagCompound tc = lst.getCompoundTagAt(i);
GlobalCoordinate coordinate = new GlobalCoordinate(new BlockPos(tc.getInteger("sourceX"), tc.getInteger("sourceY"), tc.getInteger("sourceZ")), tc.getInteger("dimension"));
RadiationSource value = new RadiationSource();
value.readFromNBT(tc);
sources.put(coordinate, value);
}
}
@Override
public void writeToNBT(NBTTagCompound tagCompound) {
NBTTagList lst = new NBTTagList();
for (Map.Entry<GlobalCoordinate, RadiationSource> entry : sources.entrySet()) {
NBTTagCompound tc = new NBTTagCompound();
tc.setInteger("dimension", entry.getKey().getDimension());
tc.setInteger("sourceX", entry.getKey().getCoordinate().getX());
tc.setInteger("sourceY", entry.getKey().getCoordinate().getY());
tc.setInteger("sourceZ", entry.getKey().getCoordinate().getZ());
entry.getValue().writeToNBT(tc);
lst.appendTag(tc);
}
tagCompound.setTag("radiation", lst);
}
public static class RadiationSource {
private float radius;
private float maxStrength; // Roughly an indication of the amount of ticks.
private float strength;
private QuadTree radiationTree;
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
public float getMaxStrength() {
return maxStrength;
}
public void setMaxStrength(float maxStrength) {
this.maxStrength = maxStrength;
}
public float getStrength() {
return strength;
}
public void setStrength(float strength) {
this.strength = strength;
}
public QuadTree getRadiationTree(World world, int centerX, int centerY, int centerZ) {
if (radiationTree == null) {
radiationTree = new QuadTree((int) (centerX-radius - 1), (int) (centerY-radius - 1), (int) (centerZ-radius-1), (int) (centerX+radius + 1), (int) (centerY+radius + 1), (int) (centerZ+radius + 1));
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
for (int x = (int) (centerX-radius); x < centerX+radius ; x++) {
for (int y = (int) (centerY-radius); y < centerY+radius ; y++) {
for (int z = (int) (centerZ-radius); z < centerZ+radius ; z++) {
pos.set(x, y, z);
IBlockState block = WorldHelper.getBlockState(world, pos);
float blocker = RadiationShieldRegistry.getBlocker(block);
if (blocker < 0.99f) {
radiationTree.addBlocker(pos, blocker);
}
}
}
}
}
return radiationTree;
}
// Update radiation for this radiation source
// @param ticks is the amount of ticks to update for.
public void update(float radius, float maxStrenght, int ticks) {
this.maxStrength = maxStrenght;
this.radius = radius;
float toadd = maxStrenght * RadiationConfiguration.strengthGrowthFactor * ticks;
if ((strength + toadd) > maxStrenght) {
toadd = maxStrenght - strength;
if (toadd < 0) {
toadd = 0;
}
}
strength += toadd;
}
public void writeToNBT(NBTTagCompound tagCompound) {
tagCompound.setFloat("radius", radius);
tagCompound.setFloat("maxStrength", maxStrength);
tagCompound.setFloat("strength", strength);
}
public void readFromNBT(NBTTagCompound tagCompound) {
this.radius = tagCompound.getFloat("radius");
this.maxStrength = tagCompound.getFloat("maxStrength");
this.strength = tagCompound.getFloat("strength");
}
}
}