made an API change to enforce the right aura methods, also add over- and underflow protection

This commit is contained in:
Ellpeck 2018-12-02 01:36:41 +01:00
parent 5abeeba757
commit 08fd796fe2
13 changed files with 50 additions and 54 deletions

View file

@ -73,7 +73,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
}
@Override
public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer) {
public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getSpotsInArea");
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++) {
@ -92,7 +92,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
@Override
public int getAuraInArea(World world, BlockPos pos, int radius) {
MutableInt result = new MutableInt(IAuraChunk.DEFAULT_AURA);
this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot.intValue()));
this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot));
return result.intValue();
}
@ -101,9 +101,8 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
MutableInt lowestAmount = new MutableInt(Integer.MAX_VALUE);
MutableObject<BlockPos> lowestSpot = new MutableObject<>();
this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> {
int amount = drainSpot.intValue();
if (amount < lowestAmount.intValue()) {
lowestAmount.setValue(amount);
if (drainSpot < lowestAmount.intValue()) {
lowestAmount.setValue(drainSpot);
lowestSpot.setValue(blockPos);
}
});
@ -118,9 +117,8 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
MutableInt highestAmount = new MutableInt(Integer.MIN_VALUE);
MutableObject<BlockPos> highestSpot = new MutableObject<>();
this.getAuraSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> {
int amount = drainSpot.intValue();
if (amount > highestAmount.intValue()) {
highestAmount.setValue(amount);
if (drainSpot > highestAmount.intValue()) {
highestAmount.setValue(drainSpot);
highestSpot.setValue(blockPos);
}
});

View file

@ -21,7 +21,6 @@ import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.ArrayList;
import java.util.HashMap;
@ -40,7 +39,7 @@ 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 = "4";
public static final String VERSION = "5";
/**
* The list of all {@link AltarRecipe} instances which are the recipes used
@ -226,7 +225,7 @@ public final class NaturesAuraAPI {
/**
* @see IAuraChunk#getSpotsInArea(World, BlockPos, int, BiConsumer)
*/
void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer);
void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer);
/**
* @see IAuraChunk#getAuraInArea(World, BlockPos, int)

View file

@ -8,7 +8,6 @@ import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.INBTSerializable;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.function.BiConsumer;
@ -59,7 +58,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable<NBTTag
* @param consumer A consumer that gets given the position and amount of
* aura in each drain spot found
*/
static void getSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer) {
static void getSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
NaturesAuraAPI.instance().getAuraSpotsInArea(world, pos, radius, consumer);
}
@ -117,7 +116,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable<NBTTag
/**
* @see #getSpotsInArea(World, BlockPos, int, BiConsumer)
*/
void getSpotsInArea(BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer);
void getSpotsInArea(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer);
/**
* Drains the given amount of Aura from the given position. Returns the
@ -165,7 +164,7 @@ public interface IAuraChunk extends ICapabilityProvider, INBTSerializable<NBTTag
*/
int storeAura(BlockPos pos, int amount);
MutableInt getDrainSpot(BlockPos pos);
int getDrainSpot(BlockPos pos);
IAuraType getType();

View file

@ -5,11 +5,10 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.mutable.MutableInt;
public interface IDrainSpotEffect {
void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot);
void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot);
boolean appliesHere(Chunk chunk, IAuraChunk auraChunk, IAuraType type);

View file

@ -6,7 +6,6 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.function.BiConsumer;
@ -32,7 +31,7 @@ public class StubHooks implements NaturesAuraAPI.IInternalHooks {
}
@Override
public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer) {
public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
}

View file

@ -43,11 +43,11 @@ public class AuraChunk implements IAuraChunk {
}
@Override
public void getSpotsInArea(BlockPos pos, int radius, BiConsumer<BlockPos, MutableInt> consumer) {
public void getSpotsInArea(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
for (Map.Entry<BlockPos, MutableInt> entry : this.drainSpots.entrySet()) {
BlockPos drainPos = entry.getKey();
if (drainPos.distanceSq(pos) <= radius * radius) {
consumer.accept(drainPos, entry.getValue());
consumer.accept(drainPos, entry.getValue().intValue());
}
}
}
@ -56,9 +56,11 @@ public class AuraChunk implements IAuraChunk {
public int drainAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) {
if (amount <= 0)
return 0;
MutableInt spot = this.getDrainSpot(pos);
if (aimForZero) {
MutableInt spot = this.getActualDrainSpot(pos, true);
int curr = spot.intValue();
if (curr < 0 && curr - amount > 0) // Underflow protection
return 0;
if (aimForZero) {
if (curr > 0 && curr - amount < 0)
amount = curr;
}
@ -78,9 +80,11 @@ public class AuraChunk implements IAuraChunk {
public int storeAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) {
if (amount <= 0)
return 0;
MutableInt spot = this.getDrainSpot(pos);
if (aimForZero) {
MutableInt spot = this.getActualDrainSpot(pos, true);
int curr = spot.intValue();
if (curr > 0 && curr + amount < 0) // Overflow protection
return 0;
if (aimForZero) {
if (curr < 0 && curr + amount > 0) {
amount = -curr;
}
@ -97,16 +101,21 @@ public class AuraChunk implements IAuraChunk {
return this.storeAura(pos, amount, true, false);
}
@Override
public MutableInt getDrainSpot(BlockPos pos) {
private MutableInt getActualDrainSpot(BlockPos pos, boolean make) {
MutableInt spot = this.drainSpots.get(pos);
if (spot == null) {
if (spot == null && make) {
spot = new MutableInt();
this.addDrainSpot(pos, spot);
}
return spot;
}
@Override
public int getDrainSpot(BlockPos pos) {
MutableInt spot = this.getActualDrainSpot(pos, false);
return spot == null ? 0 : spot.intValue();
}
private void addDrainSpot(BlockPos pos, MutableInt spot) {
int expX = pos.getX() >> 4;
int expZ = pos.getZ() >> 4;
@ -141,7 +150,7 @@ public class AuraChunk implements IAuraChunk {
MutableInt amount = entry.getValue();
for (IDrainSpotEffect effect : this.effects) {
world.profiler.func_194340_a(() -> effect.getName().toString());
effect.update(world, this.chunk, this, pos, amount);
effect.update(world, this.chunk, this, pos, amount.intValue());
world.profiler.endSection();
}
if (amount.intValue() == 0) {

View file

@ -8,15 +8,14 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.mutable.MutableInt;
public class BalanceEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "balance");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
if (spot.intValue() >= 0)
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot >= 0)
return;
int aura = IAuraChunk.getAuraInArea(world, pos, 25);
if (aura >= 0)
@ -28,7 +27,7 @@ public class BalanceEffect implements IDrainSpotEffect {
if (highestPos == null)
return;
IAuraChunk highestChunk = IAuraChunk.getAuraChunk(world, highestPos);
int toTransfer = Math.min(25, highestChunk.getDrainSpot(highestPos).intValue());
int toTransfer = Math.min(25, highestChunk.getDrainSpot(highestPos));
int stored = auraChunk.storeAura(pos, toTransfer);
highestChunk.drainAura(highestPos, stored);
}

View file

@ -14,7 +14,6 @@ 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.mutable.MutableInt;
import java.util.List;
@ -23,8 +22,8 @@ public class BreathlessEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "breathless");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
if (spot.intValue() >= 0 || world.getTotalWorldTime() % 100 != 0)
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot >= 0 || world.getTotalWorldTime() % 100 != 0)
return;
int aura = IAuraChunk.getAuraInArea(world, pos, 50);
if (aura > 0)

View file

@ -10,15 +10,14 @@ 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.mutable.MutableInt;
public class ExplosionEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "explosions");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
if (spot.intValue() >= 0 || world.getTotalWorldTime() % 40 != 0)
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot >= 0 || world.getTotalWorldTime() % 40 != 0)
return;
int aura = IAuraChunk.getAuraInArea(world, pos, 85);
if (aura > -50000)

View file

@ -15,15 +15,14 @@ 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.mutable.MutableInt;
public class GrassDieEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "grass_die");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
if (spot.intValue() < 0) {
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot < 0) {
int aura = IAuraChunk.getAuraInArea(world, pos, 50);
if (aura < 0) {
int amount = Math.min(300, Math.abs(aura) / 1000);

View file

@ -17,15 +17,14 @@ 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.mutable.MutableInt;
public class PlantBoostEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "plant_boost");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
if (spot.intValue() <= 0)
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot <= 0)
return;
int aura = IAuraChunk.getAuraInArea(world, pos, 30);
if (aura < 15000)

View file

@ -12,7 +12,6 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.ArrayList;
import java.util.List;
@ -22,9 +21,8 @@ public class ReplenishingEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "replenishing");
@Override
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, MutableInt spot) {
int amount = spot.intValue();
if (amount < 0) {
public void update(World world, Chunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
if (spot < 0) {
List<ISpotDrainable> tiles = new ArrayList<>();
Helper.getTileEntitiesInArea(world, pos, 25, tile -> {
if (tile.hasCapability(NaturesAuraAPI.capAuraContainer, null)) {
@ -41,12 +39,12 @@ public class ReplenishingEffect implements IDrainSpotEffect {
ISpotDrainable tile = tiles.get(world.rand.nextInt(tiles.size()));
if (!tile.isAcceptableType(type))
continue;
int drained = tile.drainAuraPassively(-amount, false);
int drained = tile.drainAuraPassively(-spot, false);
if (drained <= 0)
continue;
auraChunk.storeAura(pos, drained);
amount += drained;
if (amount >= drained) {
spot += drained;
if (spot >= drained) {
break;
}
}

View file

@ -57,9 +57,9 @@ public class ClientEvents {
MutableInt spots = new MutableInt();
IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 15, ((blockPos, drainSpot) -> {
spots.increment();
amount.add(drainSpot.intValue());
amount.add(drainSpot);
if (mc.player.isSneaking())
left.add(prefix + drainSpot.intValue() + " @ " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ());
left.add(prefix + drainSpot + " @ " + blockPos.getX() + " " + blockPos.getY() + " " + blockPos.getZ());
}));
left.add(prefix + "Total: " + amount.intValue() + " in " + spots.intValue() + " spots");
left.add(prefix + "Type: " + IAuraType.forWorld(mc.world).getName());