greatly increase effect powder performance

This commit is contained in:
Ellpeck 2019-02-21 12:27:54 +01:00
parent 299eb72ec0
commit f48ebebc1a
8 changed files with 98 additions and 34 deletions

View file

@ -28,6 +28,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
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.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
@ -323,4 +324,8 @@ public final class Helper {
return false; return false;
return true; return true;
} }
public static AxisAlignedBB aabb(Vec3d pos) {
return new AxisAlignedBB(pos.x, pos.y, pos.z, pos.x, pos.y, pos.z);
}
} }

View file

@ -4,10 +4,11 @@ import baubles.api.BaublesApi;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer; 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.api.multiblock.IMultiblock;
import de.ellpeck.naturesaura.blocks.multi.Multiblock; import de.ellpeck.naturesaura.blocks.multi.Multiblock;
import de.ellpeck.naturesaura.compat.Compat; 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.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; 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.apache.commons.lang3.mutable.MutableObject;
import org.lwjgl.util.vector.Vector3f; import org.lwjgl.util.vector.Vector3f;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors;
public class InternalHooks implements NaturesAuraAPI.IInternalHooks { public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
@Override @Override
@ -107,25 +108,24 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
} }
@Override @Override
public List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { public List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getActiveEffectPowders"); world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getActiveEffectPowders");
List<EntityEffectInhibitor> inhibitors = world.getEntitiesWithinAABB( List<Tuple<Vec3d, Integer>> found = new ArrayList<>();
EntityEffectInhibitor.class, area, for (Tuple<Vec3d, Integer> powder : ((WorldData) IWorldData.getWorldData(world)).effectPowders.get(name))
entity -> name.equals(entity.getInhibitedEffect())); if (area.contains(powder.getFirst()))
List<Tuple<BlockPos, Integer>> tuples = inhibitors.stream() found.add(powder);
.map(entity -> new Tuple<>(entity.getPosition(), entity.getAmount()))
.collect(Collectors.toList());
world.profiler.endSection(); world.profiler.endSection();
return tuples; return found;
} }
@Override @Override
public boolean isEffectPowderActive(World world, BlockPos pos, ResourceLocation name) { public boolean isEffectPowderActive(World world, BlockPos pos, ResourceLocation name) {
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":isEffectPowderActive"); world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":isEffectPowderActive");
List<Tuple<BlockPos, Integer>> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name); Vec3d posVec = new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
for (Tuple<BlockPos, Integer> powder : powders) { List<Tuple<Vec3d, Integer>> powders = this.getActiveEffectPowders(world, new AxisAlignedBB(pos).grow(64), name);
AxisAlignedBB bounds = new AxisAlignedBB(powder.getFirst()).grow(powder.getSecond()); for (Tuple<Vec3d, Integer> powder : powders) {
if (bounds.contains(new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5))) { AxisAlignedBB bounds = Helper.aabb(powder.getFirst()).grow(powder.getSecond());
if (bounds.contains(posVec)) {
world.profiler.endSection(); world.profiler.endSection();
return true; return true;
} }

View file

@ -20,6 +20,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
@ -295,7 +296,7 @@ public final class NaturesAuraAPI {
* @param name The registry name of the powder * @param name The registry name of the powder
* @return A list of powders' positions and ranges * @return A list of powders' positions and ranges
*/ */
List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name); List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name);
/** /**
* Returns true if there is an effect powder entity active anywhere * Returns true if there is an effect powder entity active anywhere

View file

@ -8,6 +8,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.Collections; import java.util.Collections;
@ -51,7 +52,7 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks {
} }
@Override @Override
public List<Tuple<BlockPos, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) { public List<Tuple<Vec3d, Integer>> getActiveEffectPowders(World world, AxisAlignedBB area, ResourceLocation name) {
return Collections.emptyList(); return Collections.emptyList();
} }

View file

@ -18,6 +18,7 @@ import net.minecraft.util.WeightedRandom;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreDictionary;
@ -78,19 +79,20 @@ public class OreSpawnEffect implements IDrainSpotEffect {
} }
int totalWeight = WeightedRandom.getTotalWeight(ores); int totalWeight = WeightedRandom.getTotalWeight(ores);
List<Tuple<BlockPos, Integer>> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world, List<Tuple<Vec3d, Integer>> powders = NaturesAuraAPI.instance().getActiveEffectPowders(world,
new AxisAlignedBB(pos).grow(this.dist), NAME); new AxisAlignedBB(pos).grow(this.dist), NAME);
if (powders.isEmpty()) if (powders.isEmpty())
return; return;
for (int i = 0; i < this.amount; i++) { for (int i = 0; i < this.amount; i++) {
Tuple<BlockPos, Integer> powder = powders.get(i % powders.size()); Tuple<Vec3d, Integer> powder = powders.get(i % powders.size());
BlockPos powderPos = powder.getFirst(); Vec3d powderPos = powder.getFirst();
int range = powder.getSecond(); int range = powder.getSecond();
int x = MathHelper.floor(powderPos.getX() + world.rand.nextGaussian() * range); int x = MathHelper.floor(powderPos.x + world.rand.nextGaussian() * range);
int y = MathHelper.floor(powderPos.getY() + world.rand.nextGaussian() * range); int y = MathHelper.floor(powderPos.y + world.rand.nextGaussian() * range);
int z = MathHelper.floor(powderPos.getZ() + world.rand.nextGaussian() * range); int z = MathHelper.floor(powderPos.z + world.rand.nextGaussian() * range);
BlockPos orePos = new BlockPos(x, y, z); 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); IBlockState state = world.getBlockState(orePos);
Block block = state.getBlock(); Block block = state.getBlock();
if (block != requiredBlock) if (block != requiredBlock)

View file

@ -1,9 +1,13 @@
package de.ellpeck.naturesaura.entities; 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.NaturesAura;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.api.render.IVisualizable; import de.ellpeck.naturesaura.api.render.IVisualizable;
import de.ellpeck.naturesaura.items.ItemEffectPowder; import de.ellpeck.naturesaura.items.ItemEffectPowder;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.misc.WorldData;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@ -13,12 +17,16 @@ import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource; import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
public class EntityEffectInhibitor extends Entity implements IVisualizable { public class EntityEffectInhibitor extends Entity implements IVisualizable {
private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING); private static final DataParameter<String> INHIBITED_EFFECT = EntityDataManager.createKey(EntityEffectInhibitor.class, DataSerializers.STRING);
@ -29,6 +37,52 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
super(worldIn); 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<Tuple<Vec3d, Integer>> powders = this.getPowderList();
powders.add(new Tuple<>(this.getPositionVector(), this.getAmount()));
}
private void removeFromPowderList() {
if (!this.isAddedToWorld())
return;
List<Tuple<Vec3d, Integer>> 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<Tuple<Vec3d, Integer>> getPowderList() {
ListMultimap<ResourceLocation, Tuple<Vec3d, Integer>> powders = ((WorldData) IWorldData.getWorldData(this.world)).effectPowders;
return powders.get(this.getInhibitedEffect());
}
@Override @Override
protected void entityInit() { protected void entityInit() {
this.setSize(0.25F, 0.25F); this.setSize(0.25F, 0.25F);
@ -83,7 +137,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
public void setInhibitedEffect(ResourceLocation effect) { public void setInhibitedEffect(ResourceLocation effect) {
this.removeFromPowderList();
this.dataManager.set(INHIBITED_EFFECT, effect.toString()); this.dataManager.set(INHIBITED_EFFECT, effect.toString());
this.addToPowderList();
} }
public ResourceLocation getInhibitedEffect() { public ResourceLocation getInhibitedEffect() {
@ -99,7 +155,9 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
} }
public void setAmount(int amount) { public void setAmount(int amount) {
this.removeFromPowderList();
this.dataManager.set(AMOUNT, amount); this.dataManager.set(AMOUNT, amount);
this.addToPowderList();
} }
public int getAmount() { public int getAmount() {
@ -109,9 +167,7 @@ public class EntityEffectInhibitor extends Entity implements IVisualizable {
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public AxisAlignedBB getVisualizationBounds(World world, BlockPos pos) { public AxisAlignedBB getVisualizationBounds(World world, BlockPos pos) {
return new AxisAlignedBB( return Helper.aabb(this.getPositionVector()).grow(this.getAmount());
this.posX, this.posY, this.posZ,
this.posX, this.posY, this.posZ).grow(this.getAmount());
} }
@Override @Override

View file

@ -34,8 +34,7 @@ public class CommonEvents {
@SubscribeEvent @SubscribeEvent
public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) { public void onWorldCapsAttach(AttachCapabilitiesEvent<World> event) {
World world = event.getObject(); event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData());
event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "data"), new WorldData(world));
} }
@SubscribeEvent @SubscribeEvent

View file

@ -1,5 +1,7 @@
package de.ellpeck.naturesaura.misc; 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.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.IWorldData; 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.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing; 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 net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -19,12 +23,8 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class WorldData implements IWorldData { public class WorldData implements IWorldData {
private final World world;
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>(); private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
public final ListMultimap<ResourceLocation, Tuple<Vec3d, Integer>> effectPowders = ArrayListMultimap.create();
public WorldData(World world) {
this.world = world;
}
@Override @Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {