BloodMagic/src/main/java/WayofTime/bloodmagic/inversion/InversionPillarHandler.java

235 lines
8.6 KiB
Java
Raw Normal View History

package WayofTime.bloodmagic.inversion;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
public class InversionPillarHandler
{
2016-09-11 17:58:54 -04:00
public static final double farthestDistanceSquared = 16 * 16;
public static Map<Integer, Map<EnumDemonWillType, List<BlockPos>>> pillarMap = new HashMap<Integer, Map<EnumDemonWillType, List<BlockPos>>>();
2016-09-11 17:58:54 -04:00
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;
}
}
2016-09-11 17:58:54 -04:00
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);
2016-09-11 17:58:54 -04:00
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);
2016-12-12 19:56:36 -08:00
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);
2016-12-12 19:56:36 -08:00
for (BlockPos closePos : closePosList) {
List<BlockPos> posList = posMap.get(closePos);
2016-12-12 19:56:36 -08:00
if (posList != null && !posList.contains(pos)) {
posList.add(pos);
2016-12-12 19:56:36 -08:00
} 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);
}
}
2016-09-11 17:58:54 -04:00
private static void onPillarRemoved(World world, EnumDemonWillType type, BlockPos pos)
{
System.out.println("Removing...");
2016-09-11 17:58:54 -04:00
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>();
2016-12-12 19:56:36 -08:00
for (BlockPos checkPos : uncheckedPosList) {
List<BlockPos> posList = posMap.get(checkPos);
2016-12-12 19:56:36 -08:00
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.
2016-12-12 19:56:36 -08:00
if (!checkedPosList.contains(testPos) && !uncheckedPosList.contains(testPos) && !newPosList.contains(testPos)) {
newPosList.add(testPos);
}
}
}
}
checkedPosList.addAll(uncheckedPosList);
uncheckedPosList = newPosList;
}
}
}
return checkedPosList;
}
}