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: 'maven-publish'
version = '38.0'
version = '38.1'
group = 'de.ellpeck.naturesaura' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
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": [
"naturesaura:depth_pickaxe",
"naturesaura:infused_iron_pickaxe",
"naturesaura:sky_pickaxe",
"naturesaura:depth_pickaxe"
"naturesaura:sky_pickaxe"
]
}

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;
@ -24,6 +25,7 @@ import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -33,7 +35,7 @@ public class AuraChunk implements IAuraChunk {
private final LevelChunk chunk;
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<BlockPos, Integer>[]> limitSpotCache = HashBasedTable.create();
private final List<IDrainSpotEffect> effects = new ArrayList<>();
@ -103,11 +105,12 @@ public class AuraChunk implements IAuraChunk {
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);
if (spot == null && make) {
spot = new MutableInt();
this.addDrainSpot(pos, spot);
spot = new DrainSpot(pos, 0);
this.addDrainSpot(spot);
}
return spot;
}
@ -118,20 +121,20 @@ public class AuraChunk implements IAuraChunk {
return spot == null ? 0 : spot.intValue();
}
private void addDrainSpot(BlockPos pos, MutableInt spot) {
var expX = pos.getX() >> 4;
var expZ = pos.getZ() >> 4;
private void addDrainSpot(DrainSpot spot) {
var expX = spot.pos.getX() >> 4;
var expZ = spot.pos.getZ() >> 4;
var myPos = this.chunk.getPos();
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();
for (var entry : spots.entrySet())
this.addDrainSpot(entry.getKey(), entry.getValue());
for (var spot : spots)
this.addDrainSpot(spot);
this.addOrRemoveAsActive();
}
@ -152,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) {
@ -170,7 +175,7 @@ public class AuraChunk implements IAuraChunk {
public PacketAuraChunk makePacket() {
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) {
@ -245,13 +250,8 @@ public class AuraChunk implements IAuraChunk {
@Override
public CompoundTag serializeNBT() {
var list = new ListTag();
for (var entry : this.drainSpots.entrySet()) {
var tag = new CompoundTag();
tag.putLong("pos", entry.getKey().asLong());
tag.putInt("amount", entry.getValue().intValue());
list.add(tag);
}
for (var spot : this.drainSpots.values())
list.add(spot.serializeNBT());
var compound = new CompoundTag();
compound.put("drain_spots", list);
return compound;
@ -261,12 +261,8 @@ public class AuraChunk implements IAuraChunk {
public void deserializeNBT(CompoundTag compound) {
this.drainSpots.clear();
var list = compound.getList("drain_spots", 10);
for (var base : list) {
var tag = (CompoundTag) base;
this.addDrainSpot(
BlockPos.of(tag.getLong("pos")),
new MutableInt(tag.getInt("amount")));
}
for (var base : list)
this.addDrainSpot(new DrainSpot((CompoundTag) base));
this.addOrRemoveAsActive();
}
@ -279,4 +275,30 @@ public class AuraChunk implements IAuraChunk {
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.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,7 +51,18 @@ public class SpreadEffect implements IDrainSpotEffect {
moved = bestChunk.drainAura(bestPos, perSide);
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.compat.Compat;
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.tags.BlockTagsProvider;
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.data.ExistingFileHelper;
import java.util.Comparator;
public class ItemTagProvider extends ItemTagsProvider {
public ItemTagProvider(DataGenerator generatorIn, BlockTagsProvider blockTagProvider, ExistingFileHelper helper) {
@ -29,7 +34,22 @@ public class ItemTagProvider extends ItemTagsProvider {
this.copy(BlockTags.SLABS, ItemTags.SLABS);
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);
}

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);
}
}
}

View file

@ -25,14 +25,14 @@ import net.minecraftforge.registries.ForgeRegistries;
import javax.annotation.Nullable;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
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 Map<ArmorMaterial, Item[]> SETS = new HashMap<>();
private static final Map<ArmorMaterial, Item[]> SETS = new ConcurrentHashMap<>();
private final String baseName;
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.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
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 = ColoredBlockHelper.collectBlocks("concrete");
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<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) {
List<Block> blocks = new ArrayList<>();
for (var color : DyeColor.values())
blocks.add(ForgeRegistries.BLOCKS.getValue(new ResourceLocation(color.getName() + '_' + name)));
return Collections.unmodifiableList(blocks);
return Arrays.stream(DyeColor.values()).sorted(Comparator.comparingInt(DyeColor::getId)).map(c -> {
var loc = new ResourceLocation(c.getName() + '_' + name);
var block = ForgeRegistries.BLOCKS.getValue(loc);
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) {

View file

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