From f48ebebc1a1174666a0785a167423b6f0e4f8814 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 21 Feb 2019 12:27:54 +0100 Subject: [PATCH] greatly increase effect powder performance --- .../java/de/ellpeck/naturesaura/Helper.java | 5 ++ .../de/ellpeck/naturesaura/InternalHooks.java | 28 ++++----- .../naturesaura/api/NaturesAuraAPI.java | 3 +- .../naturesaura/api/internal/StubHooks.java | 3 +- .../chunk/effect/OreSpawnEffect.java | 16 ++--- .../entities/EntityEffectInhibitor.java | 62 ++++++++++++++++++- .../naturesaura/events/CommonEvents.java | 3 +- .../ellpeck/naturesaura/misc/WorldData.java | 12 ++-- 8 files changed, 98 insertions(+), 34 deletions(-) diff --git a/src/main/java/de/ellpeck/naturesaura/Helper.java b/src/main/java/de/ellpeck/naturesaura/Helper.java index 14ce0919..079d60df 100644 --- a/src/main/java/de/ellpeck/naturesaura/Helper.java +++ b/src/main/java/de/ellpeck/naturesaura/Helper.java @@ -28,6 +28,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; @@ -323,4 +324,8 @@ public final class Helper { return false; return true; } + + public static AxisAlignedBB aabb(Vec3d pos) { + return new AxisAlignedBB(pos.x, pos.y, pos.z, pos.x, pos.y, pos.z); + } } diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 7658bf47..6e724f85 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -4,10 +4,11 @@ import baubles.api.BaublesApi; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.container.IAuraContainer; +import de.ellpeck.naturesaura.api.misc.IWorldData; import de.ellpeck.naturesaura.api.multiblock.IMultiblock; import de.ellpeck.naturesaura.blocks.multi.Multiblock; import de.ellpeck.naturesaura.compat.Compat; -import de.ellpeck.naturesaura.entities.EntityEffectInhibitor; +import de.ellpeck.naturesaura.misc.WorldData; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; @@ -22,9 +23,9 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableObject; import org.lwjgl.util.vector.Vector3f; +import java.util.ArrayList; import java.util.List; import java.util.function.BiConsumer; -import java.util.stream.Collectors; public class InternalHooks implements NaturesAuraAPI.IInternalHooks { @Override @@ -107,25 +108,24 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { } @Override - public List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { + public List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getActiveEffectPowders"); - List inhibitors = world.getEntitiesWithinAABB( - EntityEffectInhibitor.class, area, - entity -> name.equals(entity.getInhibitedEffect())); - List> tuples = inhibitors.stream() - .map(entity -> new Tuple<>(entity.getPosition(), entity.getAmount())) - .collect(Collectors.toList()); + List> found = new ArrayList<>(); + for (Tuple powder : ((WorldData) IWorldData.getWorldData(world)).effectPowders.get(name)) + if (area.contains(powder.getFirst())) + found.add(powder); world.profiler.endSection(); - return tuples; + return found; } @Override public boolean isEffectPowderActive(World world, BlockPos pos, ResourceLocation name) { world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":isEffectPowderActive"); - List> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name); - for (Tuple powder : powders) { - AxisAlignedBB bounds = new AxisAlignedBB(powder.getFirst()).grow(powder.getSecond()); - if (bounds.contains(new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5))) { + Vec3d posVec = new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + List> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name); + for (Tuple powder : powders) { + AxisAlignedBB bounds = Helper.aabb(powder.getFirst()).grow(powder.getSecond()); + if (bounds.contains(posVec)) { world.profiler.endSection(); return true; } diff --git a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java index 04205061..4739b39c 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java +++ b/src/main/java/de/ellpeck/naturesaura/api/NaturesAuraAPI.java @@ -20,6 +20,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.Tuple; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.DimensionType; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; @@ -295,7 +296,7 @@ public final class NaturesAuraAPI { * @param name The registry name of the powder * @return A list of powders' positions and ranges */ - List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name); + List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name); /** * Returns true if there is an effect powder entity active anywhere diff --git a/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java b/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java index e4a1d795..45a933ac 100644 --- a/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/api/internal/StubHooks.java @@ -8,6 +8,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.Tuple; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import java.util.Collections; @@ -51,7 +52,7 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks { } @Override - public List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { + public List> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { return Collections.emptyList(); } diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/effect/OreSpawnEffect.java b/src/main/java/de/ellpeck/naturesaura/chunk/effect/OreSpawnEffect.java index 50febdb7..9e2f016f 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/effect/OreSpawnEffect.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/effect/OreSpawnEffect.java @@ -18,6 +18,7 @@ import net.minecraft.util.WeightedRandom; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraftforge.oredict.OreDictionary; @@ -78,19 +79,20 @@ public class OreSpawnEffect implements IDrainSpotEffect { } int totalWeight = WeightedRandom.getTotalWeight(ores); - List> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world, + List> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(this.dist), NAME); if (powders.isEmpty()) return; for (int i = 0; i < this.amount; i++) { - Tuple powder = powders.get(i % powders.size()); - BlockPos powderPos = powder.getFirst(); + Tuple powder = powders.get(i % powders.size()); + Vec3d powderPos = powder.getFirst(); int range = powder.getSecond(); - int x = MathHelper.floor(powderPos.getX() + world.rand.nextGaussian() * range); - int y = MathHelper.floor(powderPos.getY() + world.rand.nextGaussian() * range); - int z = MathHelper.floor(powderPos.getZ() + world.rand.nextGaussian() * range); + int x = MathHelper.floor(powderPos.x + world.rand.nextGaussian() * range); + int y = MathHelper.floor(powderPos.y + world.rand.nextGaussian() * range); + int z = MathHelper.floor(powderPos.z + world.rand.nextGaussian() * range); BlockPos orePos = new BlockPos(x, y, z); - if (orePos.distanceSq(powderPos) <= range * range && orePos.distanceSq(pos) <= this.dist * this.dist && world.isBlockLoaded(orePos)) { + if (orePos.distanceSq(powderPos.x, powderPos.y, powderPos.z) <= range * range + && orePos.distanceSq(pos) <= this.dist * this.dist && world.isBlockLoaded(orePos)) { IBlockState state = world.getBlockState(orePos); Block block = state.getBlock(); if (block != requiredBlock) diff --git a/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java b/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java index d40ad4da..17514a1d 100644 --- a/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java +++ b/src/main/java/de/ellpeck/naturesaura/entities/EntityEffectInhibitor.java @@ -1,9 +1,13 @@ package de.ellpeck.naturesaura.entities; +import com.google.common.collect.ListMultimap; +import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.NaturesAura; +import de.ellpeck.naturesaura.api.misc.IWorldData; import de.ellpeck.naturesaura.api.render.IVisualizable; import de.ellpeck.naturesaura.items.ItemEffectPowder; import de.ellpeck.naturesaura.items.ModItems; +import de.ellpeck.naturesaura.misc.WorldData; import net.minecraft.entity.Entity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -13,12 +17,16 @@ import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; import net.minecraft.util.EntityDamageSource; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Tuple; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import java.util.List; + public class EntityEffectInhibitor extends Entity implements IVisualizable { private static final DataParameter INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING); @@ -29,6 +37,52 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable { super(worldIn); } + @Override + public void onAddedToWorld() { + super.onAddedToWorld(); + this.addToPowderList(); + } + + @Override + public void onRemovedFromWorld() { + this.removeFromPowderList(); + super.onRemovedFromWorld(); + } + + @Override + public void setPosition(double x, double y, double z) { + boolean should = x != this.posX || y != this.posY || z != this.posZ; + if (should) + this.removeFromPowderList(); + super.setPosition(x, y, z); + if (should) + this.addToPowderList(); + } + + private void addToPowderList() { + if (!this.isAddedToWorld()) + return; + List> powders = this.getPowderList(); + powders.add(new Tuple<>(this.getPositionVector(), this.getAmount())); + } + + private void removeFromPowderList() { + if (!this.isAddedToWorld()) + return; + List> powders = this.getPowderList(); + Vec3d pos = this.getPositionVector(); + for (int i = 0; i < powders.size(); i++) + if (pos.equals(powders.get(i).getFirst())) { + powders.remove(i); + break; + } + } + + private List> getPowderList() { + ListMultimap> powders = ((WorldData) IWorldData.getWorldData(this.world)).effectPowders; + return powders.get(this.getInhibitedEffect()); + } + @Override protected void entityInit() { this.setSize(0.25F, 0.25F); @@ -83,7 +137,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable { } public void setInhibitedEffect(ResourceLocation effect) { + this.removeFromPowderList(); this.dataManager.set(INHIBITED_EFFECT, effect.toString()); + this.addToPowderList(); } public ResourceLocation getInhibitedEffect() { @@ -99,7 +155,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable { } public void setAmount(int amount) { + this.removeFromPowderList(); this.dataManager.set(AMOUNT, amount); + this.addToPowderList(); } public int getAmount() { @@ -109,9 +167,7 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable { @Override @SideOnly(Side.CLIENT) public AxisAlignedBB getVisualizationBounds(World world, BlockPos pos) { - return new AxisAlignedBB( - this.posX, this.posY, this.posZ, - this.posX, this.posY, this.posZ).grow(this.getAmount()); + return Helper.aabb(this.getPositionVector()).grow(this.getAmount()); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java b/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java index aff02d31..5ee6056b 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java @@ -34,8 +34,7 @@ public class CommonEvents { @SubscribeEvent public void onWorldCapsAttach(AttachCapabilitiesEvent event) { - World world = event.getObject(); - event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData(world)); + event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData()); } @SubscribeEvent diff --git a/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java b/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java index 6efae3e8..027955f2 100644 --- a/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java +++ b/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java @@ -1,5 +1,7 @@ package de.ellpeck.naturesaura.misc; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.misc.IWorldData; @@ -10,7 +12,9 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Tuple; +import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.capabilities.Capability; import javax.annotation.Nonnull; @@ -19,12 +23,8 @@ import java.util.HashMap; import java.util.Map; public class WorldData implements IWorldData { - private final World world; private final Map enderStorages = new HashMap<>(); - - public WorldData(World world) { - this.world = world; - } + public final ListMultimap> effectPowders = ArrayListMultimap.create(); @Override public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) {