2016-02-22 01:10:56 +00:00
|
|
|
package WayofTime.bloodmagic.demonAura;
|
|
|
|
|
2018-02-16 02:49:01 +00:00
|
|
|
import WayofTime.bloodmagic.soul.DemonWillHolder;
|
|
|
|
import WayofTime.bloodmagic.soul.EnumDemonWillType;
|
2018-02-17 07:48:28 +00:00
|
|
|
import WayofTime.bloodmagic.util.BMLog;
|
2016-03-17 20:00:44 +00:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
import net.minecraft.world.chunk.Chunk;
|
|
|
|
|
2016-12-13 03:56:36 +00:00
|
|
|
import javax.annotation.Nullable;
|
2016-03-17 20:00:44 +00:00
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
2016-02-22 01:10:56 +00:00
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public class WorldDemonWillHandler {
|
2018-03-02 03:27:38 +00:00
|
|
|
public static ConcurrentHashMap<Integer, CopyOnWriteArrayList<PosXY>> dirtyChunks = new ConcurrentHashMap<>();
|
|
|
|
static ConcurrentHashMap<Integer, WillWorld> containedWills = new ConcurrentHashMap<>();
|
2016-02-22 01:10:56 +00:00
|
|
|
|
2016-12-13 03:56:36 +00:00
|
|
|
@Nullable
|
2017-08-16 04:30:48 +00:00
|
|
|
public static DemonWillHolder getWillHolder(int dim, int x, int y) {
|
2016-07-10 19:27:26 +00:00
|
|
|
WillChunk chunk = getWillChunk(dim, x, y);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (chunk != null) {
|
2016-07-10 19:27:26 +00:00
|
|
|
return chunk.getCurrentWill();
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static DemonWillHolder getWillHolder(World world, BlockPos pos) {
|
2016-07-12 20:57:22 +00:00
|
|
|
return getWillHolder(world.provider.getDimension(), pos.getX() >> 4, pos.getZ() >> 4);
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static WillWorld getWillWorld(int dim) {
|
2016-02-22 01:10:56 +00:00
|
|
|
return containedWills.get(dim);
|
|
|
|
}
|
|
|
|
|
2016-12-13 03:56:36 +00:00
|
|
|
@Nullable
|
2017-08-16 04:30:48 +00:00
|
|
|
public static WillChunk getWillChunk(int dim, int x, int y) {
|
|
|
|
if (!containedWills.containsKey(dim)) {
|
2016-03-15 00:16:31 +00:00
|
|
|
addWillWorld(dim);
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
|
2016-03-15 00:16:31 +00:00
|
|
|
return (containedWills.get(dim)).getWillChunkAt(x, y);
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static void addWillWorld(int dim) {
|
|
|
|
if (!containedWills.containsKey(dim)) {
|
2016-02-22 01:10:56 +00:00
|
|
|
containedWills.put(dim, new WillWorld(dim));
|
2018-02-17 17:54:29 +00:00
|
|
|
BMLog.DEBUG.info("Creating demon will cache for world {}", dim);
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static void removeWillWorld(int dim) {
|
2016-02-22 01:10:56 +00:00
|
|
|
containedWills.remove(dim);
|
2018-02-17 17:54:29 +00:00
|
|
|
BMLog.DEBUG.info("Removing demon will cache for world {}", dim);
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static void addWillChunk(int dim, Chunk chunk, short base, DemonWillHolder currentWill) {
|
2016-02-22 01:10:56 +00:00
|
|
|
WillWorld aw = containedWills.get(dim);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (aw == null) {
|
2016-02-22 01:10:56 +00:00
|
|
|
aw = new WillWorld(dim);
|
|
|
|
}
|
2017-08-15 03:53:42 +00:00
|
|
|
aw.getWillChunks().put(new PosXY(chunk.x, chunk.z), new WillChunk(chunk, base, currentWill));
|
2016-02-22 01:10:56 +00:00
|
|
|
|
|
|
|
containedWills.put(dim, aw);
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static void removeWillChunk(int dim, int x, int y) {
|
2016-02-22 01:10:56 +00:00
|
|
|
WillWorld aw = containedWills.get(dim);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (aw != null) {
|
2016-02-22 01:10:56 +00:00
|
|
|
WillChunk chunk = aw.getWillChunks().remove(new PosXY(x, y));
|
2017-08-16 04:30:48 +00:00
|
|
|
if (chunk != null) {
|
2016-02-22 01:10:56 +00:00
|
|
|
markChunkAsDirty(chunk, dim);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static EnumDemonWillType getHighestDemonWillType(World world, BlockPos pos) {
|
2016-02-27 03:11:28 +00:00
|
|
|
double currentMax = 0;
|
|
|
|
EnumDemonWillType currentHighest = EnumDemonWillType.DEFAULT;
|
|
|
|
|
|
|
|
WillChunk willChunk = getWillChunk(world, pos);
|
|
|
|
|
|
|
|
DemonWillHolder currentWill = willChunk.getCurrentWill();
|
2017-08-16 04:30:48 +00:00
|
|
|
for (EnumDemonWillType type : EnumDemonWillType.values()) {
|
|
|
|
if (currentWill.getWill(type) > currentMax) {
|
2016-02-27 03:11:28 +00:00
|
|
|
currentMax = currentWill.getWill(type);
|
|
|
|
currentHighest = type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return currentHighest;
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static double drainWill(World world, BlockPos pos, EnumDemonWillType type, double amount, boolean doDrain) {
|
2016-02-22 01:10:56 +00:00
|
|
|
WillChunk willChunk = getWillChunk(world, pos);
|
|
|
|
|
|
|
|
DemonWillHolder currentWill = willChunk.getCurrentWill();
|
|
|
|
double drain = Math.min(currentWill.getWill(type), amount);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (!doDrain) {
|
2016-02-22 01:10:56 +00:00
|
|
|
return drain;
|
|
|
|
}
|
|
|
|
|
|
|
|
drain = currentWill.drainWill(type, drain);
|
2016-03-17 20:00:44 +00:00
|
|
|
markChunkAsDirty(willChunk, world.provider.getDimension());
|
2016-02-22 01:10:56 +00:00
|
|
|
|
|
|
|
return drain;
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static double fillWillToMaximum(World world, BlockPos pos, EnumDemonWillType type, double amount, double max, boolean doFill) {
|
2016-02-22 01:10:56 +00:00
|
|
|
WillChunk willChunk = getWillChunk(world, pos);
|
|
|
|
|
|
|
|
DemonWillHolder currentWill = willChunk.getCurrentWill();
|
|
|
|
double fill = Math.min(amount, max - currentWill.getWill(type));
|
2017-08-16 04:30:48 +00:00
|
|
|
if (!doFill || fill <= 0) {
|
2016-09-11 14:02:06 +00:00
|
|
|
return fill > 0 ? fill : 0;
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fill = currentWill.addWill(type, amount, max);
|
2016-03-17 20:00:44 +00:00
|
|
|
markChunkAsDirty(willChunk, world.provider.getDimension());
|
2016-02-22 01:10:56 +00:00
|
|
|
|
|
|
|
return fill;
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static double fillWill(World world, BlockPos pos, EnumDemonWillType type, double amount, boolean doFill) {
|
2016-02-23 18:40:08 +00:00
|
|
|
WillChunk willChunk = getWillChunk(world, pos);
|
|
|
|
|
|
|
|
DemonWillHolder currentWill = willChunk.getCurrentWill();
|
2017-08-16 04:30:48 +00:00
|
|
|
if (!doFill) {
|
2016-02-23 18:40:08 +00:00
|
|
|
return amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentWill.addWill(type, amount);
|
2016-03-17 20:00:44 +00:00
|
|
|
markChunkAsDirty(willChunk, world.provider.getDimension());
|
2016-02-23 18:40:08 +00:00
|
|
|
|
|
|
|
return amount;
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static WillChunk getWillChunk(World world, BlockPos pos) {
|
2016-03-17 20:00:44 +00:00
|
|
|
WillChunk willChunk = getWillChunk(world.provider.getDimension(), pos.getX() >> 4, pos.getZ() >> 4);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (willChunk == null) {
|
2019-02-01 03:10:37 +00:00
|
|
|
Chunk chunk = world.getChunk(pos);
|
2016-03-15 00:16:31 +00:00
|
|
|
generateWill(chunk);
|
|
|
|
|
2016-03-17 20:00:44 +00:00
|
|
|
willChunk = getWillChunk(world.provider.getDimension(), pos.getX() >> 4, pos.getZ() >> 4);
|
2016-03-15 00:16:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return willChunk;
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static double getCurrentWill(World world, BlockPos pos, EnumDemonWillType type) {
|
2016-02-23 18:40:08 +00:00
|
|
|
WillChunk willChunk = getWillChunk(world, pos);
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
if (willChunk == null) {
|
2016-12-21 00:42:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-02-23 18:40:08 +00:00
|
|
|
DemonWillHolder currentWill = willChunk.getCurrentWill();
|
|
|
|
return currentWill.getWill(type);
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
private static void markChunkAsDirty(WillChunk chunk, int dim) {
|
|
|
|
if (chunk.isModified()) {
|
2016-02-22 01:10:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
PosXY pos = new PosXY(chunk.loc.x, chunk.loc.y);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (!dirtyChunks.containsKey(dim)) {
|
2018-03-02 03:27:38 +00:00
|
|
|
dirtyChunks.put(dim, new CopyOnWriteArrayList<>());
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
CopyOnWriteArrayList<PosXY> dc = dirtyChunks.get(dim);
|
2017-08-16 04:30:48 +00:00
|
|
|
if (!dc.contains(pos)) {
|
2016-02-22 01:10:56 +00:00
|
|
|
dc.add(pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-16 04:30:48 +00:00
|
|
|
public static void generateWill(Chunk chunk) {
|
2016-03-17 20:00:44 +00:00
|
|
|
addWillChunk(chunk.getWorld().provider.getDimension(), chunk, (short) 1, new DemonWillHolder());
|
2016-02-22 01:10:56 +00:00
|
|
|
}
|
|
|
|
}
|