package mcjty.rftools.blocks.environmental;
import mcjty.lib.varia.Coordinate;
import mcjty.lib.varia.GlobalCoordinate;
import mcjty.rftools.blocks.environmental.modules.EnvironmentModule;
import mcjty.rftools.blocks.environmental.modules.PeacefulEModule;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PeacefulAreaManager {
private static final Map<GlobalCoordinate,PeacefulArea> areas = new HashMap<GlobalCoordinate, PeacefulArea>();
public static void markArea(GlobalCoordinate coordinate, int radius, int miny, int maxy) {
if (areas.containsKey(coordinate)) {
areas.get(coordinate).touch().setArea(radius, miny, maxy);
} else {
PeacefulArea area = new PeacefulArea(radius, miny, maxy);
areas.put(coordinate, area);
}
}
public static boolean isPeaceful(GlobalCoordinate coordinate) {
if (areas.isEmpty()) {
return false;
}
List<GlobalCoordinate> toRemove = new ArrayList<GlobalCoordinate>();
boolean peaceful = false;
long curtime = System.currentTimeMillis() - 10000;
for (Map.Entry<GlobalCoordinate, PeacefulArea> entry : areas.entrySet()) {
PeacefulArea area = entry.getValue();
GlobalCoordinate entryCoordinate = entry.getKey();
if (area.in(coordinate, entryCoordinate)) {
peaceful = true;
}
if (area.getLastTouched() < curtime) {
// Hasn't been touched for at least 10 seconds. Probably no longer valid.
// To be sure we will first check this by testing if the environmental controller is still active and running.
WorldServer world = DimensionManager.getWorld(entryCoordinate.getDimension());
if (world != null) {
Coordinate c = entryCoordinate.getCoordinate();
// If the world is not loaded we don't do anything and we also don't remove the area since we have no information about it.
if (!world.getChunkProvider().chunkExists(c.getX() >> 4, c.getZ() >> 4)) {
boolean removeArea = true;
TileEntity te = world.getTileEntity(c.getX(), c.getY(), c.getZ());
if (te instanceof EnvironmentalControllerTileEntity) {
EnvironmentalControllerTileEntity controllerTileEntity = (EnvironmentalControllerTileEntity) te;
for (EnvironmentModule module : controllerTileEntity.getEnvironmentModules()) {
if (module instanceof PeacefulEModule) {
if (((PeacefulEModule) module).isActive()) {
removeArea = false;
break;
}
}
}
}
if (removeArea) {
toRemove.add(entryCoordinate);
}
}
}
}
}
for (GlobalCoordinate globalCoordinate : toRemove) {
areas.remove(globalCoordinate);
}
return peaceful;
}
public static class PeacefulArea {
private float sqradius;
private int miny;
private int maxy;
private long lastTouched;
public PeacefulArea(float radius, int miny, int maxy) {
this.sqradius = radius * radius;
this.miny = miny;
this.maxy = maxy;
touch();
}
public PeacefulArea setArea(float radius, int miny, int maxy) {
this.sqradius = radius * radius;
this.miny = miny;
this.maxy = maxy;
return this;
}
@Override
public String toString() {
return "PeacefulArea{" +
"sqradius=" + sqradius +
", miny=" + miny +
", maxy=" + maxy +
", lastTouched=" + lastTouched +
'}';
}
public long getLastTouched() {
return lastTouched;
}
public PeacefulArea touch() {
lastTouched = System.currentTimeMillis();
return this;
}
public boolean in(GlobalCoordinate coordinate, GlobalCoordinate thisCoordinate) {
if (coordinate.getDimension() != thisCoordinate.getDimension()) {
return false;
}
double py = coordinate.getCoordinate().getY();
if (py < miny || py > maxy) {
return false;
}
double px = coordinate.getCoordinate().getX() - thisCoordinate.getCoordinate().getX();
double pz = coordinate.getCoordinate().getZ() - thisCoordinate.getCoordinate().getZ();
double sqdist = px * px + pz * pz;
return sqdist < sqradius;
}
}
}