diff --git a/src/main/java/de/ellpeck/naturesaura/Helper.java b/src/main/java/de/ellpeck/naturesaura/Helper.java index 70928f9c..c1ab3a21 100644 --- a/src/main/java/de/ellpeck/naturesaura/Helper.java +++ b/src/main/java/de/ellpeck/naturesaura/Helper.java @@ -1,7 +1,7 @@ package de.ellpeck.naturesaura; import de.ellpeck.naturesaura.aura.Capabilities; -import de.ellpeck.naturesaura.aura.IAuraRecharge; +import de.ellpeck.naturesaura.aura.item.IAuraRecharge; import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -24,23 +24,21 @@ import org.lwjgl.opengl.GL11; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public final class Helper { - public static List getTileEntitiesInArea(World world, BlockPos pos, int radius) { - List tiles = new ArrayList<>(); + public static void getTileEntitiesInArea(World world, BlockPos pos, int radius, Consumer consumer) { 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++) { for (TileEntity tile : world.getChunk(x, z).getTileEntityMap().values()) { if (tile.getPos().distanceSq(pos) <= radius * radius) { - tiles.add(tile); + consumer.accept(tile); } } } } - return tiles; } public static boolean checkMultiblock(World world, BlockPos pos, BlockPos[] positions, IBlockState state, boolean blockOnly) { diff --git a/src/main/java/de/ellpeck/naturesaura/NaturesAura.java b/src/main/java/de/ellpeck/naturesaura/NaturesAura.java index 6dda54f2..c13da4a0 100644 --- a/src/main/java/de/ellpeck/naturesaura/NaturesAura.java +++ b/src/main/java/de/ellpeck/naturesaura/NaturesAura.java @@ -1,11 +1,14 @@ package de.ellpeck.naturesaura; +import de.ellpeck.naturesaura.aura.Capabilities.CapabilityAuraChunk; import de.ellpeck.naturesaura.aura.Capabilities.CapabilityAuraContainer; import de.ellpeck.naturesaura.aura.Capabilities.CapabilityAuraRecharge; -import de.ellpeck.naturesaura.aura.IAuraContainer; -import de.ellpeck.naturesaura.aura.IAuraRecharge; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; +import de.ellpeck.naturesaura.aura.item.IAuraRecharge; import de.ellpeck.naturesaura.blocks.ModBlocks; import de.ellpeck.naturesaura.compat.Compat; +import de.ellpeck.naturesaura.events.CommonEvents; import de.ellpeck.naturesaura.events.TerrainGenEvents; import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.packet.PacketHandler; @@ -49,6 +52,7 @@ public final class NaturesAura { public void preInit(FMLPreInitializationEvent event) { CapabilityManager.INSTANCE.register(IAuraContainer.class, new CapabilityAuraContainer(), () -> null); CapabilityManager.INSTANCE.register(IAuraRecharge.class, new CapabilityAuraRecharge(), () -> null); + CapabilityManager.INSTANCE.register(AuraChunk.class, new CapabilityAuraChunk(), () -> null); new ModBlocks(); new ModItems(); @@ -58,6 +62,7 @@ public final class NaturesAura { ModRegistry.preInit(event); MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEvents()); + MinecraftForge.EVENT_BUS.register(new CommonEvents()); proxy.preInit(event); } diff --git a/src/main/java/de/ellpeck/naturesaura/aura/Capabilities.java b/src/main/java/de/ellpeck/naturesaura/aura/Capabilities.java index b1504ac2..c7c2ff42 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/Capabilities.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/Capabilities.java @@ -1,5 +1,8 @@ package de.ellpeck.naturesaura.aura; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; +import de.ellpeck.naturesaura.aura.item.IAuraRecharge; import net.minecraft.nbt.NBTBase; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; @@ -16,6 +19,9 @@ public final class Capabilities { @CapabilityInject(IAuraRecharge.class) public static Capability auraRecharge; + @CapabilityInject(AuraChunk.class) + public static Capability auraChunk; + public static class CapabilityAuraContainer implements IStorage { @Override @@ -29,7 +35,7 @@ public final class Capabilities { } } - public static class CapabilityAuraRecharge implements IStorage{ + public static class CapabilityAuraRecharge implements IStorage { @Nullable @Override @@ -42,4 +48,18 @@ public final class Capabilities { } } + + public static class CapabilityAuraChunk implements IStorage { + + @Nullable + @Override + public NBTBase writeNBT(Capability capability, AuraChunk instance, EnumFacing side) { + return null; + } + + @Override + public void readNBT(Capability capability, AuraChunk instance, EnumFacing side, NBTBase nbt) { + + } + } } diff --git a/src/main/java/de/ellpeck/naturesaura/aura/chunk/AuraChunk.java b/src/main/java/de/ellpeck/naturesaura/aura/chunk/AuraChunk.java new file mode 100644 index 00000000..be330478 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/aura/chunk/AuraChunk.java @@ -0,0 +1,206 @@ +package de.ellpeck.naturesaura.aura.chunk; + +import de.ellpeck.naturesaura.Helper; +import de.ellpeck.naturesaura.aura.Capabilities; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; +import de.ellpeck.naturesaura.packet.PacketAuraChunk; +import de.ellpeck.naturesaura.packet.PacketHandler; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.INBTSerializable; +import org.apache.commons.lang3.mutable.MutableDouble; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.mutable.MutableObject; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +public class AuraChunk implements ICapabilityProvider, INBTSerializable { + + public static final int DEFAULT_AURA = 10000; + + private final Chunk chunk; + private final Map drainSpots = new HashMap<>(); + private boolean needsSync; + + public AuraChunk(Chunk chunk) { + this.chunk = chunk; + } + + public static void getSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { + 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++) { + Chunk chunk = world.getChunk(x, z); + if (chunk.hasCapability(Capabilities.auraChunk, null)) { + AuraChunk auraChunk = chunk.getCapability(Capabilities.auraChunk, null); + auraChunk.getSpotsInArea(pos, radius, consumer); + } + } + } + } + + public static int getAuraInArea(World world, BlockPos pos, int radius) { + MutableInt result = new MutableInt(DEFAULT_AURA); + getSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot.getAmount())); + return result.intValue(); + } + + public static AuraChunk getAuraChunk(World world, BlockPos pos) { + Chunk chunk = world.getChunk(pos); + if (chunk.hasCapability(Capabilities.auraChunk, null)) { + return chunk.getCapability(Capabilities.auraChunk, null); + } else { + return null; + } + } + + public static BlockPos getClosestSpot(World world, BlockPos pos, int radius, BlockPos defaultSpot) { + MutableDouble closestDist = new MutableDouble(Double.MAX_VALUE); + MutableObject closestSpot = new MutableObject<>(); + getSpotsInArea(world, pos, radius, (blockPos, drainSpot) -> { + double dist = pos.distanceSq(blockPos); + if (dist < radius * radius && dist < closestDist.doubleValue()) { + closestDist.setValue(dist); + closestSpot.setValue(blockPos); + } + }); + BlockPos closest = closestSpot.getValue(); + if (closest == null) { + closest = defaultSpot; + } + return closest; + } + + public void getSpotsInArea(BlockPos pos, int radius, BiConsumer consumer) { + for (Map.Entry entry : this.drainSpots.entrySet()) { + BlockPos drainPos = entry.getKey(); + if (drainPos.distanceSq(pos) <= radius * radius) { + consumer.accept(drainPos, entry.getValue()); + } + } + } + + public void drainAura(BlockPos pos, int amount) { + DrainSpot spot = this.getDrainSpot(pos); + spot.drain(amount); + if (spot.isEmpty()) + this.drainSpots.remove(pos); + this.markDirty(); + } + + public void storeAura(BlockPos pos, int amount) { + DrainSpot spot = this.getDrainSpot(pos); + spot.store(amount); + if (spot.isEmpty()) + this.drainSpots.remove(pos); + this.markDirty(); + } + + private DrainSpot getDrainSpot(BlockPos pos) { + DrainSpot spot = this.drainSpots.get(pos); + if (spot == null) { + spot = new DrainSpot(0); + this.drainSpots.put(pos, spot); + } + return spot; + } + + public void setSpots(Map spots) { + this.drainSpots.clear(); + this.drainSpots.putAll(spots); + } + + public void markDirty() { + this.needsSync = true; + } + + public void update() { + World world = this.chunk.getWorld(); + if (this.needsSync) { + PacketHandler.sendToAllLoaded(world, + new BlockPos(this.chunk.x * 16, 0, this.chunk.z * 16), + new PacketAuraChunk(this.chunk.x, this.chunk.z, this.drainSpots)); + this.needsSync = false; + } + + if (world.getTotalWorldTime() % 40 == 0) { + for (Map.Entry entry : this.drainSpots.entrySet()) { + BlockPos pos = entry.getKey(); + int amount = entry.getValue().getAmount(); + if (amount < 0) { + List tiles = new ArrayList<>(); + Helper.getTileEntitiesInArea(world, pos, 25, tile -> { + if (tile.hasCapability(Capabilities.auraContainer, null)) { + tiles.add(tile); + } + }); + if (!tiles.isEmpty()) { + for (int i = world.rand.nextInt(10) + 5; i >= 0; i--) { + TileEntity tile = tiles.get(world.rand.nextInt(tiles.size())); + IAuraContainer container = tile.getCapability(Capabilities.auraContainer, null); + if (!container.isArtificial()) { + int drained = container.drainAura(Math.min(-amount, 5), false); + this.storeAura(pos, drained); + amount += drained; + if (amount >= drained) { + break; + } + } + } + } + } + } + } + } + + @Override + public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { + return capability == Capabilities.auraChunk; + } + + @Nullable + @Override + public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { + return capability == Capabilities.auraChunk ? (T) this : null; + } + + @Override + public NBTTagCompound serializeNBT() { + NBTTagList list = new NBTTagList(); + for (Map.Entry entry : this.drainSpots.entrySet()) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setLong("pos", entry.getKey().toLong()); + tag.setInteger("amount", entry.getValue().getAmount()); + list.appendTag(tag); + } + + NBTTagCompound compound = new NBTTagCompound(); + compound.setTag("drain_spots", list); + return compound; + } + + @Override + public void deserializeNBT(NBTTagCompound compound) { + this.drainSpots.clear(); + NBTTagList list = compound.getTagList("drain_spots", 10); + for (NBTBase base : list) { + NBTTagCompound tag = (NBTTagCompound) base; + this.drainSpots.put( + BlockPos.fromLong(tag.getLong("pos")), + new DrainSpot(tag.getInteger("amount"))); + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/aura/chunk/DrainSpot.java b/src/main/java/de/ellpeck/naturesaura/aura/chunk/DrainSpot.java new file mode 100644 index 00000000..fb69c7d7 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/aura/chunk/DrainSpot.java @@ -0,0 +1,26 @@ +package de.ellpeck.naturesaura.aura.chunk; + +public class DrainSpot { + + private int amount; + + public DrainSpot(int amount) { + this.amount = amount; + } + + public void drain(int amount) { + this.amount -= amount; + } + + public void store(int amount) { + this.amount += amount; + } + + public int getAmount() { + return this.amount; + } + + public boolean isEmpty() { + return this.getAmount() == 0; + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/aura/BasicAuraContainer.java b/src/main/java/de/ellpeck/naturesaura/aura/container/BasicAuraContainer.java similarity index 92% rename from src/main/java/de/ellpeck/naturesaura/aura/BasicAuraContainer.java rename to src/main/java/de/ellpeck/naturesaura/aura/container/BasicAuraContainer.java index 00b6e772..127a9269 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/BasicAuraContainer.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/container/BasicAuraContainer.java @@ -1,5 +1,6 @@ -package de.ellpeck.naturesaura.aura; +package de.ellpeck.naturesaura.aura.container; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import net.minecraft.nbt.NBTTagCompound; public class BasicAuraContainer implements IAuraContainer { diff --git a/src/main/java/de/ellpeck/naturesaura/aura/FiniteAuraContainer.java b/src/main/java/de/ellpeck/naturesaura/aura/container/FiniteAuraContainer.java similarity index 86% rename from src/main/java/de/ellpeck/naturesaura/aura/FiniteAuraContainer.java rename to src/main/java/de/ellpeck/naturesaura/aura/container/FiniteAuraContainer.java index 54f97d38..f983438e 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/FiniteAuraContainer.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/container/FiniteAuraContainer.java @@ -1,4 +1,4 @@ -package de.ellpeck.naturesaura.aura; +package de.ellpeck.naturesaura.aura.container; public class FiniteAuraContainer extends BasicAuraContainer { diff --git a/src/main/java/de/ellpeck/naturesaura/aura/IAuraContainer.java b/src/main/java/de/ellpeck/naturesaura/aura/container/IAuraContainer.java similarity index 84% rename from src/main/java/de/ellpeck/naturesaura/aura/IAuraContainer.java rename to src/main/java/de/ellpeck/naturesaura/aura/container/IAuraContainer.java index a532f596..2d646be4 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/IAuraContainer.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/container/IAuraContainer.java @@ -1,4 +1,4 @@ -package de.ellpeck.naturesaura.aura; +package de.ellpeck.naturesaura.aura.container; public interface IAuraContainer { int storeAura(int amountToStore, boolean simulate); diff --git a/src/main/java/de/ellpeck/naturesaura/aura/ItemAuraContainer.java b/src/main/java/de/ellpeck/naturesaura/aura/container/ItemAuraContainer.java similarity index 94% rename from src/main/java/de/ellpeck/naturesaura/aura/ItemAuraContainer.java rename to src/main/java/de/ellpeck/naturesaura/aura/container/ItemAuraContainer.java index ed6d77c3..16c91714 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/ItemAuraContainer.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/container/ItemAuraContainer.java @@ -1,5 +1,6 @@ -package de.ellpeck.naturesaura.aura; +package de.ellpeck.naturesaura.aura.container; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/de/ellpeck/naturesaura/aura/IAuraRecharge.java b/src/main/java/de/ellpeck/naturesaura/aura/item/IAuraRecharge.java similarity index 59% rename from src/main/java/de/ellpeck/naturesaura/aura/IAuraRecharge.java rename to src/main/java/de/ellpeck/naturesaura/aura/item/IAuraRecharge.java index 96fadc2d..75302926 100644 --- a/src/main/java/de/ellpeck/naturesaura/aura/IAuraRecharge.java +++ b/src/main/java/de/ellpeck/naturesaura/aura/item/IAuraRecharge.java @@ -1,4 +1,4 @@ -package de.ellpeck.naturesaura.aura; +package de.ellpeck.naturesaura.aura.item; public interface IAuraRecharge { diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAncientLeaves.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAncientLeaves.java index 02ba0f1e..fe62a753 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAncientLeaves.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAncientLeaves.java @@ -1,7 +1,7 @@ package de.ellpeck.naturesaura.blocks.tiles; -import de.ellpeck.naturesaura.aura.FiniteAuraContainer; -import de.ellpeck.naturesaura.aura.IAuraContainer; +import de.ellpeck.naturesaura.aura.container.FiniteAuraContainer; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java index 8cd0f497..c467e5b4 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityImpl.java @@ -1,7 +1,7 @@ package de.ellpeck.naturesaura.blocks.tiles; import de.ellpeck.naturesaura.aura.Capabilities; -import de.ellpeck.naturesaura.aura.IAuraContainer; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java index fe77a7d2..644aeba0 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityNatureAltar.java @@ -2,9 +2,10 @@ package de.ellpeck.naturesaura.blocks.tiles; import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.NaturesAura; -import de.ellpeck.naturesaura.aura.BasicAuraContainer; import de.ellpeck.naturesaura.aura.Capabilities; -import de.ellpeck.naturesaura.aura.IAuraContainer; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import de.ellpeck.naturesaura.aura.container.BasicAuraContainer; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import de.ellpeck.naturesaura.packet.PacketHandler; import de.ellpeck.naturesaura.packet.PacketParticleStream; import de.ellpeck.naturesaura.packet.PacketParticles; @@ -15,15 +16,12 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.BlockPos; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; -import java.util.ArrayList; -import java.util.List; import java.util.Random; public class TileEntityNatureAltar extends TileEntityImpl implements ITickable { @@ -110,7 +108,6 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable { } }; - private final List cachedProviders = new ArrayList<>(); private final BasicAuraContainer container = new BasicAuraContainer(5000, true); public boolean structureFine; @@ -136,33 +133,24 @@ public class TileEntityNatureAltar extends TileEntityImpl implements ITickable { } if (this.structureFine) { - if (this.world.getTotalWorldTime() % 100 == 0) { - this.cachedProviders.clear(); - for (TileEntity tile : Helper.getTileEntitiesInArea(this.world, this.pos, 15)) { - if (tile.hasCapability(Capabilities.auraContainer, null) && tile != this) { - this.cachedProviders.add(tile); - } - } - } + int space = this.container.storeAura(3, true); + if (space > 0) { + int toStore = Math.min(AuraChunk.getAuraInArea(this.world, this.pos, 10), space); + if (toStore > 0) { + BlockPos spot = AuraChunk.getClosestSpot(this.world, this.pos, 10, this.pos); + AuraChunk chunk = AuraChunk.getAuraChunk(this.world, spot); - if (!this.cachedProviders.isEmpty()) { - int index = rand.nextInt(this.cachedProviders.size()); - TileEntity provider = this.cachedProviders.get(index); - if (!provider.isInvalid() && provider.hasCapability(Capabilities.auraContainer, null)) { - IAuraContainer container = provider.getCapability(Capabilities.auraContainer, null); - int stored = this.container.storeAura(container.drainAura(5, true), false); - if (stored > 0) { - container.drainAura(stored, false); + chunk.drainAura(spot, toStore); + this.container.storeAura(toStore, false); - BlockPos pos = provider.getPos(); + if (this.world.getTotalWorldTime() % 3 == 0) PacketHandler.sendToAllAround(this.world, this.pos, 32, new PacketParticleStream( - pos.getX() + 0.5F, pos.getY() + 0.5F, pos.getZ() + 0.5F, + this.pos.getX() + (float) rand.nextGaussian() * 10F, + this.pos.getY() + rand.nextFloat() * 10F, + this.pos.getZ() + (float) rand.nextGaussian() * 10F, this.pos.getX() + 0.5F, this.pos.getY() + 0.5F, this.pos.getZ() + 0.5F, - rand.nextFloat() * 0.05F + 0.05F, container.getAuraColor(), rand.nextFloat() * 1F + 1F + rand.nextFloat() * 0.05F + 0.05F, 0x89cc37, rand.nextFloat() * 1F + 1F )); - } - } else { - this.cachedProviders.remove(index); } } diff --git a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java index d50c8fd0..d684ef38 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java @@ -2,10 +2,10 @@ package de.ellpeck.naturesaura.events; import baubles.api.BaubleType; import baubles.api.BaublesApi; -import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.aura.Capabilities; -import de.ellpeck.naturesaura.aura.IAuraContainer; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; import de.ellpeck.naturesaura.blocks.tiles.TileEntityNatureAltar; import de.ellpeck.naturesaura.compat.Compat; import de.ellpeck.naturesaura.items.ModItems; @@ -31,6 +31,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import org.apache.commons.lang3.mutable.MutableInt; import java.util.List; @@ -41,11 +42,21 @@ public class ClientEvents { @SubscribeEvent public void onDebugRender(RenderGameOverlayEvent.Text event) { - if (Minecraft.getMinecraft().gameSettings.showDebugInfo) { + Minecraft mc = Minecraft.getMinecraft(); + if (mc.gameSettings.showDebugInfo) { String prefix = TextFormatting.GREEN + "[" + NaturesAura.MOD_NAME + "]" + TextFormatting.RESET + " "; List left = event.getLeft(); left.add(""); left.add(prefix + "PartScrn: " + ParticleHandler.getParticleAmount()); + + MutableInt amount = new MutableInt(AuraChunk.DEFAULT_AURA); + MutableInt spots = new MutableInt(); + AuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 15, ((blockPos, drainSpot) -> { + spots.increment(); + amount.add(drainSpot.getAmount()); + })); + left.add(prefix + "Aura: " + amount.intValue()); + left.add(prefix + "DrainSpots: " + spots.intValue()); } } @@ -79,38 +90,16 @@ public class ClientEvents { ItemStack stack = mc.player.getHeldItemMainhand(); if (mc.currentScreen == null) { if (!stack.isEmpty() && stack.getItem() == ModItems.EYE || Compat.baubles && BaublesApi.isBaubleEquipped(mc.player, ModItems.EYE) >= 0) { - int maxAura = 0; - int aura = 0; - int total = 0; - - for (TileEntity tile : Helper.getTileEntitiesInArea(mc.world, mc.player.getPosition(), 15)) { - if (tile.hasCapability(Capabilities.auraContainer, null)) { - IAuraContainer container = tile.getCapability(Capabilities.auraContainer, null); - if (!container.isArtificial()) { - maxAura += container.getMaxAura(); - aura += container.getStoredAura(); - total++; - } - } - } - GlStateManager.pushMatrix(); mc.getTextureManager().bindTexture(OVERLAYS); GlStateManager.color(0.8F, 0.25F, 0.25F); - float totalPercentage = total / 1500F; - int tHeight = MathHelper.ceil(Math.min(1F, totalPercentage) * 50); + float totalPercentage = AuraChunk.getAuraInArea(mc.world, mc.player.getPosition(), 15) / (AuraChunk.DEFAULT_AURA * 2F); + int tHeight = MathHelper.ceil(MathHelper.clamp(totalPercentage, 0F, 1F) * 50); if (tHeight < 50) - Gui.drawModalRectWithCustomSizedTexture(3, 17, 6, 12, 6, 50 - tHeight, 256, 256); + Gui.drawModalRectWithCustomSizedTexture(3, 10, 6, 12, 6, 50 - tHeight, 256, 256); if (tHeight > 0) - Gui.drawModalRectWithCustomSizedTexture(3, 17 + 50 - tHeight, 0, 12 + 50 - tHeight, 6, tHeight, 256, 256); - - GlStateManager.color(0.25F, 0.8F, 0.25F); - int aHeight = MathHelper.ceil(aura / (float) maxAura * 50); - if (aHeight < 50) - Gui.drawModalRectWithCustomSizedTexture(12, 17, 6, 12, 6, 50 - aHeight, 256, 256); - if (aHeight > 0) - Gui.drawModalRectWithCustomSizedTexture(12, 17 + 50 - aHeight, 0, 12 + 50 - aHeight, 6, aHeight, 256, 256); + Gui.drawModalRectWithCustomSizedTexture(3, 10 + 50 - tHeight, 0, 12 + 50 - tHeight, 6, tHeight, 256, 256); if (mc.objectMouseOver != null) { BlockPos pos = mc.objectMouseOver.getBlockPos(); @@ -135,13 +124,15 @@ public class ClientEvents { } if (totalPercentage > 1F) { - mc.fontRenderer.drawString("+", 3F, 9.5F, 0xBB3333, true); + mc.fontRenderer.drawString("+", 10F, 9.5F, 0xBB3333, true); + } + if (totalPercentage < 0F) { + mc.fontRenderer.drawString("-", 10F, 53.5F, 0xBB3333, true); } float scale = 0.75F; GlStateManager.scale(scale, scale, scale); mc.fontRenderer.drawString(I18n.format("info." + NaturesAura.MOD_ID + ".aura_in_area"), 3 / scale, 3 / scale, 0xBB3333, true); - mc.fontRenderer.drawString(I18n.format("info." + NaturesAura.MOD_ID + ".aura_percentage"), 12 / scale, 10 / scale, 0x33BB33, true); GlStateManager.popMatrix(); } diff --git a/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java b/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java new file mode 100644 index 00000000..9716d82d --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/events/CommonEvents.java @@ -0,0 +1,37 @@ +package de.ellpeck.naturesaura.events; + +import de.ellpeck.naturesaura.NaturesAura; +import de.ellpeck.naturesaura.aura.Capabilities; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.Iterator; + +public class CommonEvents { + + @SubscribeEvent + public void onChunkCapsAttach(AttachCapabilitiesEvent event) { + event.addCapability(new ResourceLocation(NaturesAura.MOD_ID, "aura"), new AuraChunk(event.getObject())); + } + + @SubscribeEvent + public void onWorldTick(TickEvent.WorldTickEvent event) { + if (!event.world.isRemote && event.phase == TickEvent.Phase.END) { + if (event.world.getTotalWorldTime() % 20 == 0) { + Iterator chunks = event.world.getPersistentChunkIterable(((WorldServer) event.world).getPlayerChunkMap().getChunkIterator()); + while (chunks.hasNext()) { + Chunk chunk = chunks.next(); + if (chunk.hasCapability(Capabilities.auraChunk, null)) { + AuraChunk auraChunk = chunk.getCapability(Capabilities.auraChunk, null); + auraChunk.update(); + } + } + } + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/events/TerrainGenEvents.java b/src/main/java/de/ellpeck/naturesaura/events/TerrainGenEvents.java index d3e4520f..b200c700 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/TerrainGenEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/TerrainGenEvents.java @@ -6,7 +6,6 @@ import de.ellpeck.naturesaura.blocks.tiles.TileEntityWoodStand; import de.ellpeck.naturesaura.recipes.TreeRitualRecipe; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent; @@ -22,11 +21,9 @@ public class TerrainGenEvents { BlockPos pos = event.getPos(); if (!world.isRemote) { if (Helper.checkMultiblock(world, pos, TileEntityWoodStand.GOLD_POWDER_POSITIONS, ModBlocks.GOLD_POWDER.getDefaultState(), true)) { - List tileEntities = Helper.getTileEntitiesInArea(world, pos, 5); List stands = new ArrayList<>(); List usableItems = new ArrayList<>(); - - for (TileEntity tile : tileEntities) { + Helper.getTileEntitiesInArea(world, pos, 5, tile -> { if (tile instanceof TileEntityWoodStand) { TileEntityWoodStand stand = (TileEntityWoodStand) tile; ItemStack stack = stand.items.getStackInSlot(0); @@ -35,7 +32,7 @@ public class TerrainGenEvents { stands.add(stand); } } - } + }); IBlockState sapling = world.getBlockState(pos); ItemStack saplingStack = sapling.getBlock().getItem(world, pos, sapling); diff --git a/src/main/java/de/ellpeck/naturesaura/items/ItemAuraCache.java b/src/main/java/de/ellpeck/naturesaura/items/ItemAuraCache.java index 9569fb47..f5665aa0 100644 --- a/src/main/java/de/ellpeck/naturesaura/items/ItemAuraCache.java +++ b/src/main/java/de/ellpeck/naturesaura/items/ItemAuraCache.java @@ -1,8 +1,8 @@ package de.ellpeck.naturesaura.items; import de.ellpeck.naturesaura.aura.Capabilities; -import de.ellpeck.naturesaura.aura.IAuraContainer; -import de.ellpeck.naturesaura.aura.ItemAuraContainer; +import de.ellpeck.naturesaura.aura.container.IAuraContainer; +import de.ellpeck.naturesaura.aura.container.ItemAuraContainer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketAuraChunk.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketAuraChunk.java new file mode 100644 index 00000000..313eda6d --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketAuraChunk.java @@ -0,0 +1,83 @@ +package de.ellpeck.naturesaura.packet; + +import de.ellpeck.naturesaura.NaturesAura; +import de.ellpeck.naturesaura.aura.Capabilities; +import de.ellpeck.naturesaura.aura.chunk.AuraChunk; +import de.ellpeck.naturesaura.aura.chunk.DrainSpot; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.HashMap; +import java.util.Map; + +public class PacketAuraChunk implements IMessage { + + private int chunkX; + private int chunkZ; + private Map drainSpots; + + public PacketAuraChunk(int chunkX, int chunkZ, Map drainSpots) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.drainSpots = drainSpots; + } + + public PacketAuraChunk() { + + } + + @Override + public void fromBytes(ByteBuf buf) { + this.chunkX = buf.readInt(); + this.chunkZ = buf.readInt(); + + this.drainSpots = new HashMap<>(); + int amount = buf.readInt(); + for (int i = 0; i < amount; i++) { + this.drainSpots.put( + BlockPos.fromLong(buf.readLong()), + new DrainSpot(buf.readInt()) + ); + } + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(this.chunkX); + buf.writeInt(this.chunkZ); + + buf.writeInt(this.drainSpots.size()); + for (Map.Entry entry : this.drainSpots.entrySet()) { + buf.writeLong(entry.getKey().toLong()); + buf.writeInt(entry.getValue().getAmount()); + } + } + + public static class Handler implements IMessageHandler { + + @Override + @SideOnly(Side.CLIENT) + public IMessage onMessage(PacketAuraChunk message, MessageContext ctx) { + NaturesAura.proxy.scheduleTask(() -> { + World world = Minecraft.getMinecraft().world; + if (world != null) { + Chunk chunk = world.getChunk(message.chunkX, message.chunkZ); + if (chunk.hasCapability(Capabilities.auraChunk, null)) { + AuraChunk auraChunk = chunk.getCapability(Capabilities.auraChunk, null); + auraChunk.setSpots(message.drainSpots); + } + } + }); + + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketHandler.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketHandler.java index 8b1153d4..4feffcc5 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketHandler.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketHandler.java @@ -16,6 +16,7 @@ public final class PacketHandler { network = new SimpleNetworkWrapper(NaturesAura.MOD_ID); network.registerMessage(PacketParticleStream.Handler.class, PacketParticleStream.class, 0, Side.CLIENT); network.registerMessage(PacketParticles.Handler.class, PacketParticles.class, 1, Side.CLIENT); + network.registerMessage(PacketAuraChunk.Handler.class, PacketAuraChunk.class, 2, Side.CLIENT); } public static void sendToAllLoaded(World world, BlockPos pos, IMessage message) { diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java index daf15047..6fc91f4e 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticleStream.java @@ -76,13 +76,15 @@ public class PacketParticleStream implements IMessage { message.endX - message.startX, message.endY - message.startY, message.endZ - message.startZ); - int maxAge = (int) (dir.length() / message.speed); - dir.normalise(); + if (dir.length() > 0) { + int maxAge = (int) (dir.length() / message.speed); + dir.normalise(); - NaturesAura.proxy.spawnMagicParticle(Minecraft.getMinecraft().world, - message.startX, message.startY, message.startZ, - dir.x * message.speed, dir.y * message.speed, dir.z * message.speed, - message.color, message.scale, maxAge, 0F, false, false); + NaturesAura.proxy.spawnMagicParticle(Minecraft.getMinecraft().world, + message.startX, message.startY, message.startZ, + dir.x * message.speed, dir.y * message.speed, dir.z * message.speed, + message.color, message.scale, maxAge, 0F, false, false); + } }); return null; diff --git a/src/main/resources/assets/naturesaura/lang/en_US.lang b/src/main/resources/assets/naturesaura/lang/en_US.lang index d5f963fc..58fc8d13 100644 --- a/src/main/resources/assets/naturesaura/lang/en_US.lang +++ b/src/main/resources/assets/naturesaura/lang/en_US.lang @@ -27,5 +27,4 @@ item.naturesaura.aura_cache.name=Aura Cache container.naturesaura.tree_ritual.name=Tree Infusion container.naturesaura.altar.name=Natural Altar -info.naturesaura.aura_in_area=Provider Amount -info.naturesaura.aura_percentage=Saturation \ No newline at end of file +info.naturesaura.aura_in_area=Aura Around \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/textures/gui/overlays.png b/src/main/resources/assets/naturesaura/textures/gui/overlays.png index 573b9d93..5b6bdd2b 100644 Binary files a/src/main/resources/assets/naturesaura/textures/gui/overlays.png and b/src/main/resources/assets/naturesaura/textures/gui/overlays.png differ