BloodMagic/src/main/java/WayofTime/bloodmagic/inversion/InversionPillarHandler.java
Nicholas Ignoffo 2fecb427fd Merge apibutnotreally with the main packages
Do not consider anything outside of the true API safe to use. And even then,
I'm changing things. Just wait. Please I beg you.
2018-02-15 18:49:07 -08:00

194 lines
8.1 KiB
Java

package WayofTime.bloodmagic.inversion;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.*;
public class InversionPillarHandler {
public static final double farthestDistanceSquared = 16 * 16;
public static Map<Integer, Map<EnumDemonWillType, List<BlockPos>>> pillarMap = new HashMap<Integer, Map<EnumDemonWillType, List<BlockPos>>>();
public static Map<Integer, Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>>> nearPillarMap = new HashMap<Integer, Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>>>();
public static boolean addPillarToMap(World world, EnumDemonWillType type, BlockPos pos) {
int dim = world.provider.getDimension();
if (pillarMap.containsKey(dim)) {
Map<EnumDemonWillType, List<BlockPos>> willMap = pillarMap.get(dim);
if (willMap.containsKey(type)) {
if (!willMap.get(type).contains(pos)) {
willMap.get(type).add(pos);
onPillarAdded(world, type, pos);
return true;
} else {
return false;
}
} else {
List<BlockPos> posList = new ArrayList<BlockPos>();
posList.add(pos);
willMap.put(type, posList);
onPillarAdded(world, type, pos);
return true;
}
} else {
Map<EnumDemonWillType, List<BlockPos>> willMap = new HashMap<EnumDemonWillType, List<BlockPos>>();
List<BlockPos> posList = new ArrayList<BlockPos>();
posList.add(pos);
willMap.put(type, posList);
pillarMap.put(dim, willMap);
onPillarAdded(world, type, pos);
return true;
}
}
public static boolean removePillarFromMap(World world, EnumDemonWillType type, BlockPos pos) {
int dim = world.provider.getDimension();
if (pillarMap.containsKey(dim)) {
Map<EnumDemonWillType, List<BlockPos>> willMap = pillarMap.get(dim);
if (willMap.containsKey(type)) {
if (willMap.get(type).contains(pos)) {
onPillarRemoved(world, type, pos);
return willMap.get(type).remove(pos);
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
//Assume that it has been added already.
private static void onPillarAdded(World world, EnumDemonWillType type, BlockPos pos) {
System.out.println("Adding...");
List<BlockPos> closePosList = new ArrayList<BlockPos>();
int dim = world.provider.getDimension();
if (pillarMap.containsKey(dim)) {
Map<EnumDemonWillType, List<BlockPos>> willMap = pillarMap.get(dim);
if (willMap.containsKey(type)) {
List<BlockPos> otherPosList = willMap.get(type);
for (BlockPos closePos : otherPosList) {
if (!closePos.equals(pos) && closePos.distanceSq(pos) <= farthestDistanceSquared) {
closePosList.add(closePos);
}
}
}
}
if (nearPillarMap.containsKey(dim)) {
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = nearPillarMap.get(dim);
if (willMap.containsKey(type)) {
Map<BlockPos, List<BlockPos>> posMap = willMap.get(type);
for (BlockPos closePos : closePosList) {
List<BlockPos> posList = posMap.get(closePos);
if (posList != null && !posList.contains(pos)) {
posList.add(pos);
} else {
posList = new ArrayList<BlockPos>();
posList.add(pos);
posMap.put(closePos, posList);
}
}
posMap.put(pos, closePosList);
} else {
Map<BlockPos, List<BlockPos>> posMap = new HashMap<BlockPos, List<BlockPos>>();
posMap.put(pos, closePosList);
willMap.put(type, posMap);
}
} else {
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = new HashMap<EnumDemonWillType, Map<BlockPos, List<BlockPos>>>();
Map<BlockPos, List<BlockPos>> posMap = new HashMap<BlockPos, List<BlockPos>>();
posMap.put(pos, closePosList);
willMap.put(type, posMap);
nearPillarMap.put(dim, willMap);
}
}
private static void onPillarRemoved(World world, EnumDemonWillType type, BlockPos pos) {
System.out.println("Removing...");
int dim = world.provider.getDimension();
if (nearPillarMap.containsKey(dim)) {
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = nearPillarMap.get(dim);
if (willMap.containsKey(type)) {
Map<BlockPos, List<BlockPos>> posMap = willMap.get(type);
List<BlockPos> posList = posMap.get(pos);
if (posList != null) {
Iterator<BlockPos> itr = posList.iterator();
while (itr.hasNext()) {
BlockPos checkPos = itr.next();
List<BlockPos> checkPosList = posMap.get(checkPos);
if (checkPosList != null) {
checkPosList.remove(pos);
}
}
posMap.remove(pos);
}
}
}
}
//TODO: Change to use the nearPillarMap.
public static List<BlockPos> getNearbyPillars(World world, EnumDemonWillType type, BlockPos pos) {
int dim = world.provider.getDimension();
if (nearPillarMap.containsKey(dim)) {
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = nearPillarMap.get(dim);
if (willMap.containsKey(type)) {
Map<BlockPos, List<BlockPos>> posMap = willMap.get(type);
List<BlockPos> posList = posMap.get(pos);
if (posList != null) {
return posList;
}
}
}
return new ArrayList<BlockPos>();
}
public static List<BlockPos> getAllConnectedPillars(World world, EnumDemonWillType type, BlockPos pos) {
List<BlockPos> checkedPosList = new ArrayList<BlockPos>();
List<BlockPos> uncheckedPosList = new ArrayList<BlockPos>(); //Positions where we did not check their connections.
uncheckedPosList.add(pos);
int dim = world.provider.getDimension();
if (nearPillarMap.containsKey(dim)) {
Map<EnumDemonWillType, Map<BlockPos, List<BlockPos>>> willMap = nearPillarMap.get(dim);
if (willMap.containsKey(type)) {
Map<BlockPos, List<BlockPos>> posMap = willMap.get(type);
// This is where the magic happens.
while (!uncheckedPosList.isEmpty()) {
//Positions that are new this iteration and need to be dumped into uncheckedPosList next iteration.
List<BlockPos> newPosList = new ArrayList<BlockPos>();
for (BlockPos checkPos : uncheckedPosList) {
List<BlockPos> posList = posMap.get(checkPos);
if (posList != null) {
for (BlockPos testPos : posList) {
//Check if the position has already been checked, is scheduled to be checked, or is already found it needs to be checked.
if (!checkedPosList.contains(testPos) && !uncheckedPosList.contains(testPos) && !newPosList.contains(testPos)) {
newPosList.add(testPos);
}
}
}
}
checkedPosList.addAll(uncheckedPosList);
uncheckedPosList = newPosList;
}
}
}
return checkedPosList;
}
}