mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-14 00:29:09 +01:00
added a new system that possibly massively increases aura spot performance
This commit is contained in:
parent
65879a448c
commit
06ec3cb4ff
5 changed files with 68 additions and 23 deletions
|
@ -10,6 +10,7 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl;
|
||||||
import de.ellpeck.naturesaura.chunk.AuraChunk;
|
import de.ellpeck.naturesaura.chunk.AuraChunk;
|
||||||
import de.ellpeck.naturesaura.compat.Compat;
|
import de.ellpeck.naturesaura.compat.Compat;
|
||||||
import de.ellpeck.naturesaura.misc.WorldData;
|
import de.ellpeck.naturesaura.misc.WorldData;
|
||||||
|
import de.ellpeck.naturesaura.misc.WorldData.WorldSection;
|
||||||
import net.minecraft.advancements.Advancement;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -77,17 +78,27 @@ public final class Helper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getAuraChunksWithSpotsInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
|
public static void getWorldSectionsWithSpotsInArea(World world, BlockPos pos, int radius, Consumer<WorldSection> consumer){
|
||||||
WorldData data = (WorldData) IWorldData.getWorldData(world);
|
WorldData data = (WorldData) IWorldData.getWorldData(world);
|
||||||
for (int x = pos.getX() - radius >> 4; x <= pos.getX() + radius >> 4; x++) {
|
for (int x = pos.getX() - radius >> WorldSection.B_SIZE; x <= pos.getX() + radius >> WorldSection.B_SIZE; x++) {
|
||||||
for (int z = pos.getZ() - radius >> 4; z <= pos.getZ() + radius >> 4; z++) {
|
for (int z = pos.getZ() - radius >> WorldSection.B_SIZE; z <= pos.getZ() + radius >> WorldSection.B_SIZE; z++) {
|
||||||
AuraChunk chunk = data.auraChunksWithSpots.get(ChunkPos.asLong(x, z));
|
WorldSection section = data.worldSectionsWithSpots.get(ChunkPos.asLong(x, z));
|
||||||
if (chunk != null)
|
if (section != null)
|
||||||
consumer.accept(chunk);
|
consumer.accept(section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void getAuraChunksWithSpotsInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
|
||||||
|
getWorldSectionsWithSpotsInArea(world,pos,radius, s -> {
|
||||||
|
for (AuraChunk chunk : s.chunksWithSpots.values()) {
|
||||||
|
ChunkPos chunkPos = chunk.getPos();
|
||||||
|
if (chunkPos.x >= pos.getX() - radius >> 4 && chunkPos.x <= pos.getX() + radius >> 4 && chunkPos.z >= pos.getZ() - radius >> 4 && chunkPos.z <= pos.getZ() + radius >> 4)
|
||||||
|
consumer.accept(chunk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static List<ItemFrameEntity> getAttachedItemFrames(World world, BlockPos pos) {
|
public static List<ItemFrameEntity> getAttachedItemFrames(World world, BlockPos pos) {
|
||||||
List<ItemFrameEntity> frames = world.getEntitiesWithinAABB(ItemFrameEntity.class, new AxisAlignedBB(pos).grow(0.25));
|
List<ItemFrameEntity> frames = world.getEntitiesWithinAABB(ItemFrameEntity.class, new AxisAlignedBB(pos).grow(0.25));
|
||||||
for (int i = frames.size() - 1; i >= 0; i--) {
|
for (int i = frames.size() - 1; i >= 0; i--) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect.ActiveType;
|
||||||
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
|
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
|
||||||
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
import de.ellpeck.naturesaura.api.misc.IWorldData;
|
||||||
import de.ellpeck.naturesaura.misc.WorldData;
|
import de.ellpeck.naturesaura.misc.WorldData;
|
||||||
|
import de.ellpeck.naturesaura.misc.WorldData.WorldSection;
|
||||||
import de.ellpeck.naturesaura.packet.PacketAuraChunk;
|
import de.ellpeck.naturesaura.packet.PacketAuraChunk;
|
||||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
@ -119,7 +120,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
private void addDrainSpot(BlockPos pos, MutableInt spot) {
|
private void addDrainSpot(BlockPos pos, MutableInt spot) {
|
||||||
int expX = pos.getX() >> 4;
|
int expX = pos.getX() >> 4;
|
||||||
int expZ = pos.getZ() >> 4;
|
int expZ = pos.getZ() >> 4;
|
||||||
ChunkPos myPos = this.chunk.getPos();
|
ChunkPos myPos = this.getPos();
|
||||||
if (expX != myPos.x || expZ != myPos.z)
|
if (expX != myPos.x || expZ != myPos.z)
|
||||||
throw new IllegalArgumentException("Tried to add drain spot " + pos + " to chunk at " + myPos.x + ", " + myPos.z + " when it should've been added to chunk at " + expX + ", " + expZ);
|
throw new IllegalArgumentException("Tried to add drain spot " + pos + " to chunk at " + myPos.x + ", " + myPos.z + " when it should've been added to chunk at " + expX + ", " + expZ);
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
this.drainSpots.clear();
|
this.drainSpots.clear();
|
||||||
for (Map.Entry<BlockPos, MutableInt> entry : spots.entrySet())
|
for (Map.Entry<BlockPos, MutableInt> entry : spots.entrySet())
|
||||||
this.addDrainSpot(entry.getKey(), entry.getValue());
|
this.addDrainSpot(entry.getKey(), entry.getValue());
|
||||||
this.addOrRemoveAsActive();
|
this.addOrRemoveAsActive(this.drainSpots.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,7 +143,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
public void markDirty() {
|
public void markDirty() {
|
||||||
this.chunk.markDirty();
|
this.chunk.markDirty();
|
||||||
this.needsSync = true;
|
this.needsSync = true;
|
||||||
this.addOrRemoveAsActive();
|
this.addOrRemoveAsActive(this.drainSpots.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
|
@ -156,7 +157,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.needsSync) {
|
if (this.needsSync) {
|
||||||
ChunkPos pos = this.chunk.getPos();
|
ChunkPos pos = this.getPos();
|
||||||
PacketHandler.sendToAllLoaded(world,
|
PacketHandler.sendToAllLoaded(world,
|
||||||
new BlockPos(pos.x * 16, 0, pos.z * 16),
|
new BlockPos(pos.x * 16, 0, pos.z * 16),
|
||||||
this.makePacket());
|
this.makePacket());
|
||||||
|
@ -165,7 +166,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketAuraChunk makePacket() {
|
public PacketAuraChunk makePacket() {
|
||||||
ChunkPos pos = this.chunk.getPos();
|
ChunkPos pos = this.getPos();
|
||||||
return new PacketAuraChunk(pos.x, pos.z, this.drainSpots);
|
return new PacketAuraChunk(pos.x, pos.z, this.drainSpots);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +198,27 @@ public class AuraChunk implements IAuraChunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChunkPos getPos() {
|
||||||
|
return this.chunk.getPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOrRemoveAsActive(boolean add) {
|
||||||
|
ChunkPos chunkPos = this.getPos();
|
||||||
|
long sectionPos = new ChunkPos(chunkPos.x >> WorldSection.B_SIZE - 4, chunkPos.z >> WorldSection.B_SIZE - 4).asLong();
|
||||||
|
WorldData data = (WorldData) IWorldData.getWorldData(this.chunk.getWorld());
|
||||||
|
if (add) {
|
||||||
|
WorldSection section = data.worldSectionsWithSpots.computeIfAbsent(sectionPos, l -> new WorldSection());
|
||||||
|
section.chunksWithSpots.put(chunkPos.asLong(), this);
|
||||||
|
} else {
|
||||||
|
WorldSection section = data.worldSectionsWithSpots.get(sectionPos);
|
||||||
|
if (section != null) {
|
||||||
|
section.chunksWithSpots.remove(chunkPos.asLong());
|
||||||
|
if (section.chunksWithSpots.size() <= 0)
|
||||||
|
data.worldSectionsWithSpots.remove(sectionPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT serializeNBT() {
|
public CompoundNBT serializeNBT() {
|
||||||
ListNBT list = new ListNBT();
|
ListNBT list = new ListNBT();
|
||||||
|
@ -222,16 +244,7 @@ public class AuraChunk implements IAuraChunk {
|
||||||
BlockPos.fromLong(tag.getLong("pos")),
|
BlockPos.fromLong(tag.getLong("pos")),
|
||||||
new MutableInt(tag.getInt("amount")));
|
new MutableInt(tag.getInt("amount")));
|
||||||
}
|
}
|
||||||
this.addOrRemoveAsActive();
|
this.addOrRemoveAsActive(this.drainSpots.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOrRemoveAsActive() {
|
|
||||||
long chunkPos = this.chunk.getPos().asLong();
|
|
||||||
WorldData data = (WorldData) IWorldData.getWorldData(this.chunk.getWorld());
|
|
||||||
if (this.drainSpots.size() > 0) {
|
|
||||||
data.auraChunksWithSpots.put(chunkPos, this);
|
|
||||||
} else {
|
|
||||||
data.auraChunksWithSpots.remove(chunkPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,13 +81,15 @@ public class ClientEvents {
|
||||||
MutableInt amount = new MutableInt(IAuraChunk.DEFAULT_AURA);
|
MutableInt amount = new MutableInt(IAuraChunk.DEFAULT_AURA);
|
||||||
MutableInt spots = new MutableInt();
|
MutableInt spots = new MutableInt();
|
||||||
MutableInt chunks = new MutableInt();
|
MutableInt chunks = new MutableInt();
|
||||||
|
MutableInt sections = new MutableInt();
|
||||||
IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 35, (blockPos, drainSpot) -> {
|
IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 35, (blockPos, drainSpot) -> {
|
||||||
spots.increment();
|
spots.increment();
|
||||||
amount.add(drainSpot);
|
amount.add(drainSpot);
|
||||||
});
|
});
|
||||||
Helper.getAuraChunksWithSpotsInArea(mc.world, mc.player.getPosition(), 35, c -> chunks.increment());
|
Helper.getAuraChunksWithSpotsInArea(mc.world, mc.player.getPosition(), 35, c -> chunks.increment());
|
||||||
|
Helper.getWorldSectionsWithSpotsInArea(mc.world, mc.player.getPosition(), 35, s -> sections.increment());
|
||||||
NumberFormat format = NumberFormat.getInstance();
|
NumberFormat format = NumberFormat.getInstance();
|
||||||
left.add(prefix + "A: " + format.format(amount.intValue()) + " (S: " + spots.intValue() + ", C: " + chunks.intValue() + ")");
|
left.add(prefix + "A: " + format.format(amount.intValue()) + " (S: " + spots.intValue() + ", C: " + chunks.intValue() + ", WS: " + sections.intValue() + ")");
|
||||||
left.add(prefix + "AT: " + IAuraType.forWorld(mc.world).getName());
|
left.add(prefix + "AT: " + IAuraType.forWorld(mc.world).getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.IChunk;
|
||||||
import net.minecraft.world.gen.GenerationStage.Decoration;
|
import net.minecraft.world.gen.GenerationStage.Decoration;
|
||||||
import net.minecraft.world.server.ChunkHolder;
|
import net.minecraft.world.server.ChunkHolder;
|
||||||
import net.minecraft.world.server.ChunkManager;
|
import net.minecraft.world.server.ChunkManager;
|
||||||
|
@ -29,6 +31,7 @@ import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
||||||
|
import net.minecraftforge.event.world.ChunkEvent;
|
||||||
import net.minecraftforge.event.world.ChunkWatchEvent;
|
import net.minecraftforge.event.world.ChunkWatchEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||||
|
@ -69,6 +72,16 @@ public class CommonEvents {
|
||||||
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunkProvider(chunk));
|
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunkProvider(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onChunkUnload(ChunkEvent.Unload event) {
|
||||||
|
IChunk chunk = event.getChunk();
|
||||||
|
if (chunk instanceof Chunk) {
|
||||||
|
IAuraChunk auraChunk = ((Chunk) chunk).getCapability(NaturesAuraAPI.capAuraChunk).orElse(null);
|
||||||
|
if (auraChunk instanceof AuraChunk)
|
||||||
|
((AuraChunk) auraChunk).addOrRemoveAsActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
|
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
|
||||||
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData());
|
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData());
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.*;
|
||||||
|
|
||||||
public class WorldData implements IWorldData {
|
public class WorldData implements IWorldData {
|
||||||
public final ListMultimap<ResourceLocation, Tuple<Vector3d, Integer>> effectPowders = ArrayListMultimap.create();
|
public final ListMultimap<ResourceLocation, Tuple<Vector3d, Integer>> effectPowders = ArrayListMultimap.create();
|
||||||
public final Long2ObjectOpenHashMap<AuraChunk> auraChunksWithSpots = new Long2ObjectOpenHashMap<>();
|
public final Long2ObjectOpenHashMap<WorldSection> worldSectionsWithSpots = new Long2ObjectOpenHashMap<>();
|
||||||
public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>();
|
public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>();
|
||||||
public final Set<TileEntitySpawnLamp> spawnLamps = new HashSet<>();
|
public final Set<TileEntitySpawnLamp> spawnLamps = new HashSet<>();
|
||||||
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
|
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
|
||||||
|
@ -100,4 +100,10 @@ public class WorldData implements IWorldData {
|
||||||
if (this.recentlyConvertedMossStones.size() > 512)
|
if (this.recentlyConvertedMossStones.size() > 512)
|
||||||
this.recentlyConvertedMossStones.remove(0);
|
this.recentlyConvertedMossStones.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class WorldSection {
|
||||||
|
// each world section is 128 blocks big
|
||||||
|
public static final int B_SIZE = 7;
|
||||||
|
public final Long2ObjectOpenHashMap<AuraChunk> chunksWithSpots = new Long2ObjectOpenHashMap<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue