added a max range for aura spreading

addresses issues like #314
This commit is contained in:
Ell 2023-06-27 10:40:31 +02:00
parent e7d79baaba
commit 5868fd6dce
18 changed files with 68 additions and 23 deletions

View file

@ -26,6 +26,7 @@ public final class ModConfig {
public ConfigValue<Integer> fieldCreatorRange;
public ConfigValue<Double> auraToRFRatio;
public ConfigValue<Integer> maxAnimalsAroundPowder;
public ConfigValue<Integer> maxAuraSpreadRange;
public ConfigValue<Boolean> rfConverter;
public ConfigValue<Boolean> chunkLoader;
@ -88,6 +89,10 @@ public final class ModConfig {
.comment("The maximum amount of animals that can be around the powder of fertility before it stops working")
.translation("config." + NaturesAura.MOD_ID + ".maxAnimalsAroundPowder")
.define("maxAnimalsAroundPowder", 200);
this.maxAuraSpreadRange = builder
.comment("The maximum amount of blocks that aura can spread from an initial position before it starts fizzling out. It's recommended to lower this value on a large server to avoid lag caused by players chunk-loading their bases for extended amounts of time without an Aura Detector present.")
.translation("config." + NaturesAura.MOD_ID + ".maxAuraSpreadRange")
.define("maxAuraSpreadRange", 150);
builder.pop();
builder.push("features");

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.api.aura.chunk;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
@ -151,6 +152,8 @@ public interface IAuraChunk extends INBTSerializable<CompoundTag> {
*/
int storeAura(BlockPos pos, int amount);
AuraChunk.DrainSpot getActualDrainSpot(BlockPos pos, boolean make);
int getDrainSpot(BlockPos pos);
IAuraType getType();

View file

@ -1,6 +1,7 @@
package de.ellpeck.naturesaura.api.aura.chunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
@ -10,7 +11,7 @@ import net.minecraft.world.level.chunk.LevelChunk;
public interface IDrainSpotEffect {
void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot);
void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot);
boolean appliesHere(LevelChunk chunk, IAuraChunk auraChunk, IAuraType type);

View file

@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.chunk;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import de.ellpeck.naturesaura.ModConfig;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
@ -104,7 +105,8 @@ public class AuraChunk implements IAuraChunk {
return this.storeAura(pos, amount, true, false);
}
private DrainSpot getActualDrainSpot(BlockPos pos, boolean make) {
@Override
public DrainSpot getActualDrainSpot(BlockPos pos, boolean make) {
var spot = this.drainSpots.get(pos);
if (spot == null && make) {
spot = new DrainSpot(pos, 0);
@ -153,11 +155,13 @@ public class AuraChunk implements IAuraChunk {
public void update() {
var level = this.chunk.getLevel();
for (var entry : this.drainSpots.entrySet()) {
var pos = entry.getKey();
var amount = entry.getValue();
for (var spot : this.drainSpots.values()) {
for (var effect : this.effects)
effect.update(level, this.chunk, this, pos, amount.intValue());
effect.update(level, this.chunk, this, spot.pos, spot.intValue(), spot);
// cause this spot to fizzle out if it's over the range limit
if (spot.intValue() > 0 && spot.originalSpreadPos != null && !spot.originalSpreadPos.closerThan(spot.pos, ModConfig.instance.maxAuraSpreadRange.get()))
this.drainAura(spot.pos, spot.intValue());
}
if (this.needsSync) {
@ -275,6 +279,7 @@ public class AuraChunk implements IAuraChunk {
public static class DrainSpot extends MutableInt {
public final BlockPos pos;
public BlockPos originalSpreadPos;
public DrainSpot(BlockPos pos, int value) {
super(value);
@ -283,12 +288,16 @@ public class AuraChunk implements IAuraChunk {
public DrainSpot(CompoundTag tag) {
this(BlockPos.of(tag.getLong("pos")), tag.getInt("amount"));
if (tag.contains("original_spread_pos"))
this.originalSpreadPos = BlockPos.of(tag.getLong("original_spread_pos"));
}
public CompoundTag serializeNBT() {
var ret = new CompoundTag();
ret.putLong("pos", this.pos.asLong());
ret.putInt("amount", this.intValue());
if (this.originalSpreadPos != null)
ret.putLong("original_spread_pos", this.originalSpreadPos.asLong());
return ret;
}
}

View file

@ -5,6 +5,7 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.LivingEntity;
@ -51,7 +52,7 @@ public class AngerEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 100 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -6,6 +6,7 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
@ -63,7 +64,7 @@ public class AnimalEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 200 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -4,6 +4,7 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
@ -15,7 +16,7 @@ public class BalanceEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "balance");
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (spot < 100000)
return;
if (level.getGameTime() % 200 != 0)

View file

@ -5,6 +5,7 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.potion.ModPotions;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
@ -54,7 +55,7 @@ public class BreathlessEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 100 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -6,6 +6,7 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
@ -53,7 +54,7 @@ public class CacheRechargeEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (!this.calcValues(level, pos, spot))
return;
var players = level.getEntitiesOfClass(Player.class, this.bb);

View file

@ -5,6 +5,7 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
@ -54,7 +55,7 @@ public class ExplosionEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 40 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.ModBlocks;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
@ -57,7 +58,7 @@ public class GrassDieEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (!this.calcValues(level, pos, spot))
return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) {

View file

@ -6,6 +6,7 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
@ -56,7 +57,7 @@ public class NetherDecayEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (!this.calcValues(level, pos, spot))
return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) {

View file

@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.ModBlocks;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos;
@ -57,7 +58,7 @@ public class NetherGrassEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 40 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.api.misc.WeightedOre;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
@ -73,7 +74,7 @@ public class OreSpawnEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (level.getGameTime() % 40 != 0)
return;
if (!this.calcValues(level, pos, spot))

View file

@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos;
@ -63,7 +64,7 @@ public class PlantBoostEffect implements IDrainSpotEffect {
}
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (!this.calcValues(level, pos, spot))
return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) {

View file

@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.chunk.ISpotDrainable;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
@ -20,7 +21,7 @@ public class ReplenishingEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "replenishing");
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (spot < 0) {
List<ISpotDrainable> tiles = new ArrayList<>();
Helper.getBlockEntitiesInArea(level, pos, 25, tile -> {

View file

@ -4,6 +4,7 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
@ -16,7 +17,7 @@ public class SpreadEffect implements IDrainSpotEffect {
public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "spread");
@Override
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot, AuraChunk.DrainSpot actualSpot) {
if (Math.abs(spot) < 500000 || Math.abs(IAuraChunk.getAuraInArea(level, pos, 25) - IAuraChunk.DEFAULT_AURA) < 1000000)
return;
var drain = spot > 0;
@ -50,9 +51,20 @@ public class SpreadEffect implements IDrainSpotEffect {
moved = bestChunk.drainAura(bestPos, perSide);
auraChunk.storeAura(pos, moved);
}
if (moved != 0) {
var bestSpot = bestChunk.getActualDrainSpot(bestPos, false);
if (bestSpot != null && bestSpot.originalSpreadPos == null) {
// propagate the spread position that we came from
bestSpot.originalSpreadPos = actualSpot.originalSpreadPos;
// if we didn't come from a spread position, our own position is the original
if (bestSpot.originalSpreadPos == null)
bestSpot.originalSpreadPos = pos;
bestChunk.markDirty();
}
toMove -= moved;
}
}
}
@Override
public boolean appliesHere(LevelChunk chunk, IAuraChunk auraChunk, IAuraType type) {

View file

@ -424,9 +424,12 @@ public class ClientEvents {
if (ClientEvents.hoveringAuraSpot != null) {
var format = NumberFormat.getInstance();
var amount = IAuraChunk.getAuraChunk(mc.level, ClientEvents.hoveringAuraSpot).getDrainSpot(ClientEvents.hoveringAuraSpot);
var color = amount > 0 ? ChatFormatting.GREEN : ChatFormatting.RED;
mc.font.drawShadow(stack, color + format.format(amount), res.getGuiScaledWidth() / 2F + 5, res.getGuiScaledHeight() / 2F - 11, 0xFFFFFF);
var spot = IAuraChunk.getAuraChunk(mc.level, ClientEvents.hoveringAuraSpot).getActualDrainSpot(ClientEvents.hoveringAuraSpot, false);
var color = spot.intValue() > 0 ? ChatFormatting.GREEN : ChatFormatting.RED;
mc.font.drawShadow(stack, "Pos: " + spot.pos.toShortString(), res.getGuiScaledWidth() / 2F + 5, res.getGuiScaledHeight() / 2F - 20, 0xFFFFFF);
mc.font.drawShadow(stack, "Amount: " + color + format.format(spot.intValue()), res.getGuiScaledWidth() / 2F + 5, res.getGuiScaledHeight() / 2F - 10, 0xFFFFFF);
if (spot.originalSpreadPos != null)
mc.font.drawShadow(stack, "Dist from Original: " + (int) Math.sqrt(spot.pos.distSqr(spot.originalSpreadPos)) + " (" + spot.originalSpreadPos.toShortString() + ")", res.getGuiScaledWidth() / 2F + 5, res.getGuiScaledHeight() / 2F, 0xFFFFFF);
}
}
}