Compare commits

...

6 commits

Author SHA1 Message Date
Ell 0a0fc6b4ab 38.1 2023-06-27 11:08:44 +02:00
Ell 856f01b7ca added tools to their respective tags
closes #312
2023-06-27 11:04:11 +02:00
Ell f87ef01caa fixed color changer crashing on white blocks, and not working with stained glass
closes #304
2023-06-27 10:59:05 +02:00
Ell 8bbc14652c made armor set calc concurrency-proof
closes #305
2023-06-27 10:42:53 +02:00
Ell 5868fd6dce added a max range for aura spreading
addresses issues like #314
2023-06-27 10:40:31 +02:00
Ell e7d79baaba turn drain spots into a class 2023-06-27 09:44:19 +02:00
29 changed files with 187 additions and 78 deletions

View file

@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = '38.0' version = '38.1'
group = 'de.ellpeck.naturesaura' // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = 'de.ellpeck.naturesaura' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'NaturesAura' archivesBaseName = 'NaturesAura'

View file

@ -0,0 +1,7 @@
{
"values": [
"naturesaura:depth_axe",
"naturesaura:infused_iron_axe",
"naturesaura:sky_axe"
]
}

View file

@ -0,0 +1,7 @@
{
"values": [
"naturesaura:depth_hoe",
"naturesaura:infused_iron_hoe",
"naturesaura:sky_hoe"
]
}

View file

@ -0,0 +1,7 @@
{
"values": [
"naturesaura:depth_pickaxe",
"naturesaura:infused_iron_pickaxe",
"naturesaura:sky_pickaxe"
]
}

View file

@ -0,0 +1,7 @@
{
"values": [
"naturesaura:depth_shovel",
"naturesaura:infused_iron_shovel",
"naturesaura:sky_shovel"
]
}

View file

@ -0,0 +1,7 @@
{
"values": [
"naturesaura:depth_sword",
"naturesaura:infused_iron_sword",
"naturesaura:sky_sword"
]
}

View file

@ -1,7 +1,7 @@
{ {
"values": [ "values": [
"naturesaura:depth_pickaxe",
"naturesaura:infused_iron_pickaxe", "naturesaura:infused_iron_pickaxe",
"naturesaura:sky_pickaxe", "naturesaura:sky_pickaxe"
"naturesaura:depth_pickaxe"
] ]
} }

View file

@ -26,6 +26,7 @@ public final class ModConfig {
public ConfigValue<Integer> fieldCreatorRange; public ConfigValue<Integer> fieldCreatorRange;
public ConfigValue<Double> auraToRFRatio; public ConfigValue<Double> auraToRFRatio;
public ConfigValue<Integer> maxAnimalsAroundPowder; public ConfigValue<Integer> maxAnimalsAroundPowder;
public ConfigValue<Integer> maxAuraSpreadRange;
public ConfigValue<Boolean> rfConverter; public ConfigValue<Boolean> rfConverter;
public ConfigValue<Boolean> chunkLoader; 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") .comment("The maximum amount of animals that can be around the powder of fertility before it stops working")
.translation("config." + NaturesAura.MOD_ID + ".maxAnimalsAroundPowder") .translation("config." + NaturesAura.MOD_ID + ".maxAnimalsAroundPowder")
.define("maxAnimalsAroundPowder", 200); .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.pop();
builder.push("features"); 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.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -151,6 +152,8 @@ public interface IAuraChunk extends INBTSerializable<CompoundTag> {
*/ */
int storeAura(BlockPos pos, int amount); int storeAura(BlockPos pos, int amount);
AuraChunk.DrainSpot getActualDrainSpot(BlockPos pos, boolean make);
int getDrainSpot(BlockPos pos); int getDrainSpot(BlockPos pos);
IAuraType getType(); IAuraType getType();

View file

@ -1,6 +1,7 @@
package de.ellpeck.naturesaura.api.aura.chunk; package de.ellpeck.naturesaura.api.aura.chunk;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -10,7 +11,7 @@ import net.minecraft.world.level.chunk.LevelChunk;
public interface IDrainSpotEffect { 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); 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.HashBasedTable;
import com.google.common.collect.Table; import com.google.common.collect.Table;
import de.ellpeck.naturesaura.ModConfig;
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.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
@ -24,6 +25,7 @@ import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -33,7 +35,7 @@ public class AuraChunk implements IAuraChunk {
private final LevelChunk chunk; private final LevelChunk chunk;
private final IAuraType type; private final IAuraType type;
private final Map<BlockPos, MutableInt> drainSpots = new ConcurrentHashMap<>(); private final Map<BlockPos, DrainSpot> drainSpots = new ConcurrentHashMap<>();
private final Table<BlockPos, Integer, Pair<Integer, Integer>> auraAndSpotAmountCache = HashBasedTable.create(); private final Table<BlockPos, Integer, Pair<Integer, Integer>> auraAndSpotAmountCache = HashBasedTable.create();
private final Table<BlockPos, Integer, Pair<BlockPos, Integer>[]> limitSpotCache = HashBasedTable.create(); private final Table<BlockPos, Integer, Pair<BlockPos, Integer>[]> limitSpotCache = HashBasedTable.create();
private final List<IDrainSpotEffect> effects = new ArrayList<>(); private final List<IDrainSpotEffect> effects = new ArrayList<>();
@ -103,11 +105,12 @@ public class AuraChunk implements IAuraChunk {
return this.storeAura(pos, amount, true, false); return this.storeAura(pos, amount, true, false);
} }
private MutableInt getActualDrainSpot(BlockPos pos, boolean make) { @Override
public DrainSpot getActualDrainSpot(BlockPos pos, boolean make) {
var spot = this.drainSpots.get(pos); var spot = this.drainSpots.get(pos);
if (spot == null && make) { if (spot == null && make) {
spot = new MutableInt(); spot = new DrainSpot(pos, 0);
this.addDrainSpot(pos, spot); this.addDrainSpot(spot);
} }
return spot; return spot;
} }
@ -118,20 +121,20 @@ public class AuraChunk implements IAuraChunk {
return spot == null ? 0 : spot.intValue(); return spot == null ? 0 : spot.intValue();
} }
private void addDrainSpot(BlockPos pos, MutableInt spot) { private void addDrainSpot(DrainSpot spot) {
var expX = pos.getX() >> 4; var expX = spot.pos.getX() >> 4;
var expZ = pos.getZ() >> 4; var expZ = spot.pos.getZ() >> 4;
var myPos = this.chunk.getPos(); var myPos = this.chunk.getPos();
if (expX != myPos.x || expZ != myPos.z) if (expX != myPos.x || expZ != myPos.z)
throw new IllegalArgumentException("Tried to add drain spot " + pos + " to chunk at " + myPos.x + ", " + myPos.z + " when it should've been added to chunk at " + expX + ", " + expZ); throw new IllegalArgumentException("Tried to add drain spot " + spot.pos + " to chunk at " + myPos.x + ", " + myPos.z + " when it should've been added to chunk at " + expX + ", " + expZ);
this.drainSpots.put(pos, spot); this.drainSpots.put(spot.pos, spot);
} }
public void setSpots(Map<BlockPos, MutableInt> spots) { public void setSpots(Collection<DrainSpot> spots) {
this.drainSpots.clear(); this.drainSpots.clear();
for (var entry : spots.entrySet()) for (var spot : spots)
this.addDrainSpot(entry.getKey(), entry.getValue()); this.addDrainSpot(spot);
this.addOrRemoveAsActive(); this.addOrRemoveAsActive();
} }
@ -152,11 +155,13 @@ public class AuraChunk implements IAuraChunk {
public void update() { public void update() {
var level = this.chunk.getLevel(); var level = this.chunk.getLevel();
for (var entry : this.drainSpots.entrySet()) { for (var spot : this.drainSpots.values()) {
var pos = entry.getKey();
var amount = entry.getValue();
for (var effect : this.effects) 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) { if (this.needsSync) {
@ -170,7 +175,7 @@ public class AuraChunk implements IAuraChunk {
public PacketAuraChunk makePacket() { public PacketAuraChunk makePacket() {
var pos = this.chunk.getPos(); var pos = this.chunk.getPos();
return new PacketAuraChunk(pos.x, pos.z, this.drainSpots); return new PacketAuraChunk(pos.x, pos.z, this.drainSpots.values());
} }
public void getSpots(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) { public void getSpots(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
@ -245,13 +250,8 @@ public class AuraChunk implements IAuraChunk {
@Override @Override
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
var list = new ListTag(); var list = new ListTag();
for (var entry : this.drainSpots.entrySet()) { for (var spot : this.drainSpots.values())
var tag = new CompoundTag(); list.add(spot.serializeNBT());
tag.putLong("pos", entry.getKey().asLong());
tag.putInt("amount", entry.getValue().intValue());
list.add(tag);
}
var compound = new CompoundTag(); var compound = new CompoundTag();
compound.put("drain_spots", list); compound.put("drain_spots", list);
return compound; return compound;
@ -261,12 +261,8 @@ public class AuraChunk implements IAuraChunk {
public void deserializeNBT(CompoundTag compound) { public void deserializeNBT(CompoundTag compound) {
this.drainSpots.clear(); this.drainSpots.clear();
var list = compound.getList("drain_spots", 10); var list = compound.getList("drain_spots", 10);
for (var base : list) { for (var base : list)
var tag = (CompoundTag) base; this.addDrainSpot(new DrainSpot((CompoundTag) base));
this.addDrainSpot(
BlockPos.of(tag.getLong("pos")),
new MutableInt(tag.getInt("amount")));
}
this.addOrRemoveAsActive(); this.addOrRemoveAsActive();
} }
@ -279,4 +275,30 @@ public class AuraChunk implements IAuraChunk {
data.auraChunksWithSpots.remove(chunkPos); data.auraChunksWithSpots.remove(chunkPos);
} }
} }
public static class DrainSpot extends MutableInt {
public final BlockPos pos;
public BlockPos originalSpreadPos;
public DrainSpot(BlockPos pos, int value) {
super(value);
this.pos = pos;
}
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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@ -51,7 +52,7 @@ public class AngerEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 100 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -63,7 +64,7 @@ public class AnimalEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 200 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level; 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"); public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "balance");
@Override @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) if (spot < 100000)
return; return;
if (level.getGameTime() % 200 != 0) 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.potion.ModPotions; import de.ellpeck.naturesaura.potion.ModPotions;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -54,7 +55,7 @@ public class BreathlessEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 100 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -53,7 +54,7 @@ public class CacheRechargeEffect implements IDrainSpotEffect {
} }
@Override @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)) if (!this.calcValues(level, pos, spot))
return; return;
var players = level.getEntitiesOfClass(Player.class, this.bb); 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -54,7 +55,7 @@ public class ExplosionEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 40 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.ModBlocks; import de.ellpeck.naturesaura.blocks.ModBlocks;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -57,7 +58,7 @@ public class GrassDieEffect implements IDrainSpotEffect {
} }
@Override @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)) if (!this.calcValues(level, pos, spot))
return; return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) { 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -56,7 +57,7 @@ public class NetherDecayEffect implements IDrainSpotEffect {
} }
@Override @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)) if (!this.calcValues(level, pos, spot))
return; return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) { 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.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.blocks.ModBlocks; import de.ellpeck.naturesaura.blocks.ModBlocks;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -57,7 +58,7 @@ public class NetherGrassEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 40 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.api.misc.WeightedOre; import de.ellpeck.naturesaura.api.misc.WeightedOre;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -73,7 +74,7 @@ public class OreSpawnEffect implements IDrainSpotEffect {
} }
@Override @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) if (level.getGameTime() % 40 != 0)
return; return;
if (!this.calcValues(level, pos, spot)) 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; 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.PacketHandler;
import de.ellpeck.naturesaura.packet.PacketParticles; import de.ellpeck.naturesaura.packet.PacketParticles;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -63,7 +64,7 @@ public class PlantBoostEffect implements IDrainSpotEffect {
} }
@Override @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)) if (!this.calcValues(level, pos, spot))
return; return;
for (var i = this.amount / 2 + level.random.nextInt(this.amount / 2); i >= 0; i--) { 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.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.chunk.ISpotDrainable; import de.ellpeck.naturesaura.api.aura.chunk.ISpotDrainable;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level; 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"); public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "replenishing");
@Override @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) { if (spot < 0) {
List<ISpotDrainable> tiles = new ArrayList<>(); List<ISpotDrainable> tiles = new ArrayList<>();
Helper.getBlockEntitiesInArea(level, pos, 25, tile -> { 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.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; 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"); public static final ResourceLocation NAME = new ResourceLocation(NaturesAura.MOD_ID, "spread");
@Override @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) if (Math.abs(spot) < 500000 || Math.abs(IAuraChunk.getAuraInArea(level, pos, 25) - IAuraChunk.DEFAULT_AURA) < 1000000)
return; return;
var drain = spot > 0; var drain = spot > 0;
@ -50,7 +51,18 @@ public class SpreadEffect implements IDrainSpotEffect {
moved = bestChunk.drainAura(bestPos, perSide); moved = bestChunk.drainAura(bestPos, perSide);
auraChunk.storeAura(pos, moved); auraChunk.storeAura(pos, moved);
} }
toMove -= 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;
}
} }
} }

View file

@ -3,6 +3,9 @@ package de.ellpeck.naturesaura.data;
import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.compat.Compat; import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.items.tools.*;
import de.ellpeck.naturesaura.reg.IModItem;
import de.ellpeck.naturesaura.reg.ModRegistry;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataGenerator;
import net.minecraft.data.tags.BlockTagsProvider; import net.minecraft.data.tags.BlockTagsProvider;
import net.minecraft.data.tags.ItemTagsProvider; import net.minecraft.data.tags.ItemTagsProvider;
@ -13,6 +16,8 @@ import net.minecraft.world.item.Item;
import net.minecraftforge.common.Tags; import net.minecraftforge.common.Tags;
import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.common.data.ExistingFileHelper;
import java.util.Comparator;
public class ItemTagProvider extends ItemTagsProvider { public class ItemTagProvider extends ItemTagsProvider {
public ItemTagProvider(DataGenerator generatorIn, BlockTagsProvider blockTagProvider, ExistingFileHelper helper) { public ItemTagProvider(DataGenerator generatorIn, BlockTagsProvider blockTagProvider, ExistingFileHelper helper) {
@ -29,7 +34,22 @@ public class ItemTagProvider extends ItemTagsProvider {
this.copy(BlockTags.SLABS, ItemTags.SLABS); this.copy(BlockTags.SLABS, ItemTags.SLABS);
this.tag(Tags.Items.RODS_WOODEN).add(ModItems.ANCIENT_STICK); this.tag(Tags.Items.RODS_WOODEN).add(ModItems.ANCIENT_STICK);
this.tag(ItemTags.CLUSTER_MAX_HARVESTABLES).add(ModItems.INFUSED_IRON_PICKAXE, ModItems.SKY_PICKAXE, ModItems.DEPTH_PICKAXE);
// sort these so that they don't change the json every time we run data (because it's a set)
ModRegistry.ALL_ITEMS.stream().sorted(Comparator.comparing(IModItem::getBaseName)).filter(i -> i instanceof Item).map(i -> (Item) i).forEach(i -> {
if (i instanceof ItemPickaxe) {
this.tag(ItemTags.CLUSTER_MAX_HARVESTABLES).add(i);
this.tag(Tags.Items.TOOLS_PICKAXES).add(i);
} else if (i instanceof ItemAxe) {
this.tag(Tags.Items.TOOLS_AXES).add(i);
} else if (i instanceof ItemHoe) {
this.tag(Tags.Items.TOOLS_HOES).add(i);
} else if (i instanceof ItemSword) {
this.tag(Tags.Items.TOOLS_SWORDS).add(i);
} else if (i instanceof ItemShovel) {
this.tag(Tags.Items.TOOLS_SHOVELS).add(i);
}
});
Compat.addItemTags(this); Compat.addItemTags(this);
} }

View file

@ -424,9 +424,12 @@ public class ClientEvents {
if (ClientEvents.hoveringAuraSpot != null) { if (ClientEvents.hoveringAuraSpot != null) {
var format = NumberFormat.getInstance(); var format = NumberFormat.getInstance();
var amount = IAuraChunk.getAuraChunk(mc.level, ClientEvents.hoveringAuraSpot).getDrainSpot(ClientEvents.hoveringAuraSpot); var spot = IAuraChunk.getAuraChunk(mc.level, ClientEvents.hoveringAuraSpot).getActualDrainSpot(ClientEvents.hoveringAuraSpot, false);
var color = amount > 0 ? ChatFormatting.GREEN : ChatFormatting.RED; var color = spot.intValue() > 0 ? ChatFormatting.GREEN : ChatFormatting.RED;
mc.font.drawShadow(stack, color + format.format(amount), res.getGuiScaledWidth() / 2F + 5, res.getGuiScaledHeight() / 2F - 11, 0xFFFFFF); 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);
} }
} }
} }

View file

@ -25,14 +25,14 @@ import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class ItemArmor extends ArmorItem implements IModItem { public class ItemArmor extends ArmorItem implements IModItem {
private static final AttributeModifier SKY_MOVEMENT_MODIFIER = new AttributeModifier(UUID.fromString("c1f96acc-e117-4dc1-a351-e196a4de6071"), NaturesAura.MOD_ID + ":sky_movement_speed", 0.15F, AttributeModifier.Operation.MULTIPLY_TOTAL); private static final AttributeModifier SKY_MOVEMENT_MODIFIER = new AttributeModifier(UUID.fromString("c1f96acc-e117-4dc1-a351-e196a4de6071"), NaturesAura.MOD_ID + ":sky_movement_speed", 0.15F, AttributeModifier.Operation.MULTIPLY_TOTAL);
private static final Map<ArmorMaterial, Item[]> SETS = new HashMap<>(); private static final Map<ArmorMaterial, Item[]> SETS = new ConcurrentHashMap<>();
private final String baseName; private final String baseName;
public ItemArmor(String baseName, ArmorMaterial materialIn, EquipmentSlot equipmentSlotIn) { public ItemArmor(String baseName, ArmorMaterial materialIn, EquipmentSlot equipmentSlotIn) {

View file

@ -3,11 +3,11 @@ package de.ellpeck.naturesaura.misc;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Comparator;
import java.util.List; import java.util.List;
public final class ColoredBlockHelper { public final class ColoredBlockHelper {
@ -17,15 +17,18 @@ public final class ColoredBlockHelper {
public static final List<Block> CONCRETE_POWDER = ColoredBlockHelper.collectBlocks("concrete_powder"); public static final List<Block> CONCRETE_POWDER = ColoredBlockHelper.collectBlocks("concrete_powder");
public static final List<Block> CONCRETE = ColoredBlockHelper.collectBlocks("concrete"); public static final List<Block> CONCRETE = ColoredBlockHelper.collectBlocks("concrete");
public static final List<Block> GLASS = ColoredBlockHelper.collectBlocks("stained_glass"); public static final List<Block> GLASS = ColoredBlockHelper.collectBlocks("stained_glass");
public static final List<Block> GLASS_PANE = ColoredBlockHelper.collectBlocks("glass_pane"); public static final List<Block> GLASS_PANE = ColoredBlockHelper.collectBlocks("stained_glass_pane");
public static final List<Block> CARPET = ColoredBlockHelper.collectBlocks("carpet"); public static final List<Block> CARPET = ColoredBlockHelper.collectBlocks("carpet");
public static final List<List<Block>> LISTS = Arrays.asList(ColoredBlockHelper.WOOL, ColoredBlockHelper.TERRACOTTA, ColoredBlockHelper.CONCRETE_POWDER, ColoredBlockHelper.CONCRETE, ColoredBlockHelper.GLASS, ColoredBlockHelper.GLASS_PANE, ColoredBlockHelper.CARPET); public static final List<List<Block>> LISTS = Arrays.asList(ColoredBlockHelper.WOOL, ColoredBlockHelper.TERRACOTTA, ColoredBlockHelper.CONCRETE_POWDER, ColoredBlockHelper.CONCRETE, ColoredBlockHelper.GLASS, ColoredBlockHelper.GLASS_PANE, ColoredBlockHelper.CARPET);
private static List<Block> collectBlocks(String name) { private static List<Block> collectBlocks(String name) {
List<Block> blocks = new ArrayList<>(); return Arrays.stream(DyeColor.values()).sorted(Comparator.comparingInt(DyeColor::getId)).map(c -> {
for (var color : DyeColor.values()) var loc = new ResourceLocation(c.getName() + '_' + name);
blocks.add(ForgeRegistries.BLOCKS.getValue(new ResourceLocation(color.getName() + '_' + name))); var block = ForgeRegistries.BLOCKS.getValue(loc);
return Collections.unmodifiableList(blocks); if (block == null || block == Blocks.AIR)
throw new IllegalStateException("Couldn't find block with name " + loc);
return block;
}).toList();
} }
public static List<Block> getBlocksContaining(Block block) { public static List<Block> getBlocksContaining(Block block) {

View file

@ -4,23 +4,22 @@ import de.ellpeck.naturesaura.NaturesAura;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.chunk.AuraChunk; import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.events.ClientEvents; import de.ellpeck.naturesaura.events.ClientEvents;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Map; import java.util.Collection;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
public class PacketAuraChunk { public class PacketAuraChunk {
private int chunkX; private int chunkX;
private int chunkZ; private int chunkZ;
private Map<BlockPos, MutableInt> drainSpots; private Collection<AuraChunk.DrainSpot> drainSpots;
public PacketAuraChunk(int chunkX, int chunkZ, Map<BlockPos, MutableInt> drainSpots) { public PacketAuraChunk(int chunkX, int chunkZ, Collection<AuraChunk.DrainSpot> drainSpots) {
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
this.drainSpots = drainSpots; this.drainSpots = drainSpots;
@ -34,14 +33,10 @@ public class PacketAuraChunk {
packet.chunkX = buf.readInt(); packet.chunkX = buf.readInt();
packet.chunkZ = buf.readInt(); packet.chunkZ = buf.readInt();
packet.drainSpots = new HashMap<>(); packet.drainSpots = new ArrayList<>();
var amount = buf.readInt(); var amount = buf.readInt();
for (var i = 0; i < amount; i++) { for (var i = 0; i < amount; i++)
packet.drainSpots.put( packet.drainSpots.add(new AuraChunk.DrainSpot(buf.readNbt()));
BlockPos.of(buf.readLong()),
new MutableInt(buf.readInt())
);
}
return packet; return packet;
} }
@ -51,10 +46,8 @@ public class PacketAuraChunk {
buf.writeInt(packet.chunkZ); buf.writeInt(packet.chunkZ);
buf.writeInt(packet.drainSpots.size()); buf.writeInt(packet.drainSpots.size());
for (var entry : packet.drainSpots.entrySet()) { for (var entry : packet.drainSpots)
buf.writeLong(entry.getKey().asLong()); buf.writeNbt(entry.serializeNBT());
buf.writeInt(entry.getValue().intValue());
}
} }
public static void onMessage(PacketAuraChunk message, Supplier<NetworkEvent.Context> ctx) { public static void onMessage(PacketAuraChunk message, Supplier<NetworkEvent.Context> ctx) {