mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-25 12:58:33 +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.compat.Compat;
|
||||
import de.ellpeck.naturesaura.misc.WorldData;
|
||||
import de.ellpeck.naturesaura.misc.WorldData.WorldSection;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -77,17 +78,27 @@ public final class Helper {
|
|||
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);
|
||||
for (int x = pos.getX() - radius >> 4; x <= pos.getX() + radius >> 4; x++) {
|
||||
for (int z = pos.getZ() - radius >> 4; z <= pos.getZ() + radius >> 4; z++) {
|
||||
AuraChunk chunk = data.auraChunksWithSpots.get(ChunkPos.asLong(x, z));
|
||||
if (chunk != null)
|
||||
consumer.accept(chunk);
|
||||
for (int x = pos.getX() - radius >> WorldSection.B_SIZE; x <= pos.getX() + radius >> WorldSection.B_SIZE; x++) {
|
||||
for (int z = pos.getZ() - radius >> WorldSection.B_SIZE; z <= pos.getZ() + radius >> WorldSection.B_SIZE; z++) {
|
||||
WorldSection section = data.worldSectionsWithSpots.get(ChunkPos.asLong(x, z));
|
||||
if (section != null)
|
||||
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) {
|
||||
List<ItemFrameEntity> frames = world.getEntitiesWithinAABB(ItemFrameEntity.class, new AxisAlignedBB(pos).grow(0.25));
|
||||
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.misc.IWorldData;
|
||||
import de.ellpeck.naturesaura.misc.WorldData;
|
||||
import de.ellpeck.naturesaura.misc.WorldData.WorldSection;
|
||||
import de.ellpeck.naturesaura.packet.PacketAuraChunk;
|
||||
import de.ellpeck.naturesaura.packet.PacketHandler;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -119,7 +120,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
private void addDrainSpot(BlockPos pos, MutableInt spot) {
|
||||
int expX = pos.getX() >> 4;
|
||||
int expZ = pos.getZ() >> 4;
|
||||
ChunkPos myPos = this.chunk.getPos();
|
||||
ChunkPos myPos = this.getPos();
|
||||
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);
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
this.drainSpots.clear();
|
||||
for (Map.Entry<BlockPos, MutableInt> entry : spots.entrySet())
|
||||
this.addDrainSpot(entry.getKey(), entry.getValue());
|
||||
this.addOrRemoveAsActive();
|
||||
this.addOrRemoveAsActive(this.drainSpots.size() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,7 +143,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
public void markDirty() {
|
||||
this.chunk.markDirty();
|
||||
this.needsSync = true;
|
||||
this.addOrRemoveAsActive();
|
||||
this.addOrRemoveAsActive(this.drainSpots.size() > 0);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
|
@ -156,7 +157,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
}
|
||||
|
||||
if (this.needsSync) {
|
||||
ChunkPos pos = this.chunk.getPos();
|
||||
ChunkPos pos = this.getPos();
|
||||
PacketHandler.sendToAllLoaded(world,
|
||||
new BlockPos(pos.x * 16, 0, pos.z * 16),
|
||||
this.makePacket());
|
||||
|
@ -165,7 +166,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
}
|
||||
|
||||
public PacketAuraChunk makePacket() {
|
||||
ChunkPos pos = this.chunk.getPos();
|
||||
ChunkPos pos = this.getPos();
|
||||
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
|
||||
public CompoundNBT serializeNBT() {
|
||||
ListNBT list = new ListNBT();
|
||||
|
@ -222,16 +244,7 @@ public class AuraChunk implements IAuraChunk {
|
|||
BlockPos.fromLong(tag.getLong("pos")),
|
||||
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 spots = new MutableInt();
|
||||
MutableInt chunks = new MutableInt();
|
||||
MutableInt sections = new MutableInt();
|
||||
IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 35, (blockPos, drainSpot) -> {
|
||||
spots.increment();
|
||||
amount.add(drainSpot);
|
||||
});
|
||||
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();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.gen.GenerationStage.Decoration;
|
||||
import net.minecraft.world.server.ChunkHolder;
|
||||
import net.minecraft.world.server.ChunkManager;
|
||||
|
@ -29,6 +31,7 @@ import net.minecraftforge.event.AttachCapabilitiesEvent;
|
|||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.ChunkWatchEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
|
@ -69,6 +72,16 @@ public class CommonEvents {
|
|||
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
|
||||
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
|
||||
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData());
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.*;
|
|||
|
||||
public class WorldData implements IWorldData {
|
||||
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 Set<TileEntitySpawnLamp> spawnLamps = new HashSet<>();
|
||||
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
|
||||
|
@ -100,4 +100,10 @@ public class WorldData implements IWorldData {
|
|||
if (this.recentlyConvertedMossStones.size() > 512)
|
||||
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