improve aura spot performance by combining aura and spot amount

Improves #216
This commit is contained in:
Ell 2021-06-28 14:31:37 +02:00
parent 19cc8f4a52
commit 20ca7711ff
10 changed files with 66 additions and 14 deletions

View file

@ -18,12 +18,14 @@ import net.minecraft.world.World;
import org.apache.commons.lang3.mutable.MutableFloat;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
@Override
public boolean extractAuraFromPlayer(PlayerEntity player, int amount, boolean simulate) {
return this.auraPlayerInteraction(player, amount, true, simulate);
@ -127,6 +129,17 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
return result.intValue();
}
@Override
public Pair<Integer, Integer> getAuraAndSpotAmountInArea(World world, BlockPos pos, int radius) {
MutableInt spots = new MutableInt();
MutableInt aura = new MutableInt(IAuraChunk.DEFAULT_AURA);
this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> {
aura.add(drainSpot);
spots.increment();
});
return Pair.of(aura.intValue(), spots.intValue());
}
@Override
public int triangulateAuraInArea(World world, BlockPos pos, int radius) {
MutableFloat result = new MutableFloat(IAuraChunk.DEFAULT_AURA);

View file

@ -26,6 +26,7 @@ import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.HashMap;
@ -40,6 +41,7 @@ import java.util.function.Supplier;
* internal mod functions not exposed to the API.
*/
public final class NaturesAuraAPI {
public static final String MOD_ID = "naturesaura";
public static final String API_ID = MOD_ID + "api";
public static final String VERSION = "9";
@ -300,6 +302,11 @@ public final class NaturesAuraAPI {
*/
int getAuraInArea(World world, BlockPos pos, int radius);
/**
* @see IAuraChunk#getAuraAndSpotAmountInArea(World, BlockPos, int)
*/
Pair<Integer, Integer> getAuraAndSpotAmountInArea(World world, BlockPos pos, int radius);
/**
* @see IAuraChunk#triangulateAuraInArea(IWorld, BlockPos, int)
*/

View file

@ -8,6 +8,7 @@ import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.util.INBTSerializable;
import org.apache.commons.lang3.tuple.Pair;
import java.util.function.BiConsumer;
@ -20,6 +21,7 @@ import java.util.function.BiConsumer;
* class.
*/
public interface IAuraChunk extends INBTSerializable<CompoundNBT> {
/**
* The default amount of Aura that a chunk has stored
*/
@ -82,6 +84,22 @@ public interface IAuraChunk extends INBTSerializable<CompoundNBT> {
return NaturesAuraAPI.instance().getAuraInArea((World) world, pos, radius);
}
/**
* Convenience method that combines {@link #getAuraInArea(IWorld, BlockPos,
* int)} and {@link #getSpotAmountInArea(IWorld, BlockPos, int)} to increase
* performance.
*
* @param world The world
* @param pos The center position
* @param radius The radius around the center to search for spots in
* @return A pair of the amount of aura in the area as the {@link
* Pair#getLeft()} entry, and the amount of aura spots in the area as the
* {@link Pair#getRight()} entry
*/
static Pair<Integer, Integer> getAuraAndSpotAmountInArea(World world, BlockPos pos, int radius) {
return NaturesAuraAPI.instance().getAuraAndSpotAmountInArea(world, pos, radius);
}
/**
* Convenience method that adds up all of the aura from each drain spot from
* {@link #getSpotsInArea(IWorld, BlockPos, int, BiConsumer)}, but

View file

@ -22,6 +22,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Comparator;
import java.util.List;
@ -37,10 +38,11 @@ public class AnimalEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot <= 0)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 30);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 30);
int aura = auraAndSpots.getLeft();
if (aura < 1500000)
return false;
this.chance = Math.min(50, MathHelper.ceil(Math.abs(aura) / 500000F / IAuraChunk.getSpotAmountInArea(world, pos, 30)));
this.chance = Math.min(50, MathHelper.ceil(Math.abs(aura) / 500000F / auraAndSpots.getRight()));
if (this.chance <= 0)
return false;
int dist = MathHelper.clamp(Math.abs(aura) / 150000, 5, 35);

View file

@ -15,6 +15,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
@ -28,12 +29,13 @@ public class CacheRechargeEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot < 100000)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 20);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 20);
int aura = auraAndSpots.getLeft();
if (aura < 1500000)
return false;
int dist = MathHelper.clamp(aura / 3500, 3, 15);
this.bb = new AxisAlignedBB(pos).grow(dist);
this.amount = MathHelper.ceil(aura / 250F / IAuraChunk.getSpotAmountInArea(world, pos, 20));
this.amount = MathHelper.ceil(aura / 250F / auraAndSpots.getRight());
return true;
}

View file

@ -15,6 +15,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.tuple.Pair;
public class GrassDieEffect implements IDrainSpotEffect {
@ -25,9 +26,10 @@ public class GrassDieEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot < 0) {
int aura = IAuraChunk.getAuraInArea(world, pos, 50);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 50);
int aura = auraAndSpots.getLeft();
if (aura < 0) {
this.amount = Math.min(300, MathHelper.ceil(Math.abs(aura) / 100000F / IAuraChunk.getSpotAmountInArea(world, pos, 50)));
this.amount = Math.min(300, MathHelper.ceil(Math.abs(aura) / 100000F / auraAndSpots.getRight()));
if (this.amount > 1) {
this.dist = MathHelper.clamp(Math.abs(aura) / 75000, 5, 75);
return true;

View file

@ -20,6 +20,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.tuple.Pair;
public class NetherDecayEffect implements IDrainSpotEffect {
@ -31,10 +32,11 @@ public class NetherDecayEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot >= 0)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 50);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 50);
int aura = auraAndSpots.getLeft();
if (aura >= 0)
return false;
this.amount = Math.min(300, MathHelper.ceil(Math.abs(aura) / 50000F / IAuraChunk.getSpotAmountInArea(world, pos, 50)));
this.amount = Math.min(300, MathHelper.ceil(Math.abs(aura) / 50000F / auraAndSpots.getRight()));
if (this.amount <= 1)
return false;
this.dist = MathHelper.clamp(Math.abs(aura) / 50000, 5, 75);

View file

@ -20,6 +20,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.Tags;
import org.apache.commons.lang3.tuple.Pair;
public class NetherGrassEffect implements IDrainSpotEffect {
@ -31,10 +32,11 @@ public class NetherGrassEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot <= 0)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 30);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 30);
int aura = auraAndSpots.getLeft();
if (aura < 1500000)
return false;
this.amount = Math.min(20, MathHelper.ceil(Math.abs(aura) / 100000F / IAuraChunk.getSpotAmountInArea(world, pos, 30)));
this.amount = Math.min(20, MathHelper.ceil(Math.abs(aura) / 100000F / auraAndSpots.getRight()));
if (this.amount <= 1)
return false;
this.dist = MathHelper.clamp(Math.abs(aura) / 100000, 5, 35);

View file

@ -26,6 +26,7 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.FakePlayerFactory;
import org.apache.commons.lang3.tuple.Pair;
import java.util.HashSet;
import java.util.List;
@ -42,10 +43,11 @@ public class OreSpawnEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot <= 0)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 30);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 30);
int aura = auraAndSpots.getLeft();
if (aura <= 2000000)
return false;
this.amount = Math.min(20, MathHelper.ceil(Math.abs(aura) / 300000F / IAuraChunk.getSpotAmountInArea(world, pos, 30)));
this.amount = Math.min(20, MathHelper.ceil(Math.abs(aura) / 300000F / auraAndSpots.getRight()));
if (this.amount <= 0)
return false;
this.dist = MathHelper.clamp(Math.abs(aura) / 150000, 5, 20);

View file

@ -19,6 +19,7 @@ import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.server.ServerWorld;
import org.apache.commons.lang3.tuple.Pair;
public class PlantBoostEffect implements IDrainSpotEffect {
@ -30,10 +31,11 @@ public class PlantBoostEffect implements IDrainSpotEffect {
private boolean calcValues(World world, BlockPos pos, Integer spot) {
if (spot <= 0)
return false;
int aura = IAuraChunk.getAuraInArea(world, pos, 30);
Pair<Integer, Integer> auraAndSpots = IAuraChunk.getAuraAndSpotAmountInArea(world, pos, 30);
int aura = auraAndSpots.getLeft();
if (aura < 1500000)
return false;
this.amount = Math.min(45, MathHelper.ceil(Math.abs(aura) / 100000F / IAuraChunk.getSpotAmountInArea(world, pos, 30)));
this.amount = Math.min(45, MathHelper.ceil(Math.abs(aura) / 100000F / auraAndSpots.getRight()));
if (this.amount <= 1)
return false;
this.dist = MathHelper.clamp(Math.abs(aura) / 150000, 5, 35);