diff --git a/src/main/java/org/KaiFlo/SolarCell/Components/EnergyConsumer/Implementations/EnergyConsumerComponent.java b/src/main/java/org/KaiFlo/SolarCell/Components/EnergyConsumer/Implementations/EnergyConsumerComponent.java index 69a2f51..5ab9796 100644 --- a/src/main/java/org/KaiFlo/SolarCell/Components/EnergyConsumer/Implementations/EnergyConsumerComponent.java +++ b/src/main/java/org/KaiFlo/SolarCell/Components/EnergyConsumer/Implementations/EnergyConsumerComponent.java @@ -11,7 +11,7 @@ import org.KaiFlo.SolarCell.Components.EnergyConsumer.IEnergyConsumer; import org.KaiFlo.SolarCell.SolarCellPlugin; import org.checkerframework.checker.nullness.compatqual.NullableDecl; -import static org.KaiFlo.SolarCell.Helpers.BlockHelper.LOGGER; +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.HyLogger; public class EnergyConsumerComponent implements Component, IEnergyConsumer { public static final BuilderCodec CODEC = BuilderCodec.builder(EnergyConsumerComponent.class, EnergyConsumerComponent::new) @@ -59,7 +59,7 @@ public class EnergyConsumerComponent implements Component, IEnergyCo try { super.clone(); } catch (CloneNotSupportedException e) { - LOGGER.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); + HyLogger.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); } return new EnergyConsumerComponent().copyFrom(this); } diff --git a/src/main/java/org/KaiFlo/SolarCell/Components/EnergySource/Implementations/EnergySourceComponent.java b/src/main/java/org/KaiFlo/SolarCell/Components/EnergySource/Implementations/EnergySourceComponent.java index 4a7712d..90f08b4 100644 --- a/src/main/java/org/KaiFlo/SolarCell/Components/EnergySource/Implementations/EnergySourceComponent.java +++ b/src/main/java/org/KaiFlo/SolarCell/Components/EnergySource/Implementations/EnergySourceComponent.java @@ -11,10 +11,9 @@ import org.KaiFlo.SolarCell.Components.EnergySource.IEnergySource; import org.KaiFlo.SolarCell.SolarCellPlugin; import org.checkerframework.checker.nullness.compatqual.NullableDecl; -import static org.KaiFlo.SolarCell.Helpers.BlockHelper.LOGGER; +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.HyLogger; public class EnergySourceComponent implements Component, IEnergySource { - @SuppressWarnings("unchecked") public static final BuilderCodec CODEC = BuilderCodec.builder(EnergySourceComponent.class, EnergySourceComponent::new) .append(new KeyedCodec<>("GeneratesPerTick", Codec.LONG), (component, value) -> component.generatesPerTick = value, @@ -27,7 +26,7 @@ public class EnergySourceComponent implements Component, IEnergySour (component, value) -> component.energyCapacity = value, (component) -> component.energyCapacity ) - .addValidator(Validators.or(Validators.equal(-1L), Validators.greaterThanOrEqual(0L))) + .addValidator(Validators.greaterThanOrEqual(-1L)) .documentation("EnergyCapacity defines how long energy can be produced (Set to -1 if endless energy production)") .add() .build(); @@ -51,7 +50,7 @@ public class EnergySourceComponent implements Component, IEnergySour try { super.clone(); } catch (CloneNotSupportedException e) { - LOGGER.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); + HyLogger.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); } return new EnergySourceComponent().copyFrom(this); } diff --git a/src/main/java/org/KaiFlo/SolarCell/Components/EnergyStorage/Implementations/EnergyStorageComponent.java b/src/main/java/org/KaiFlo/SolarCell/Components/EnergyStorage/Implementations/EnergyStorageComponent.java index 23ef505..5b6bf94 100644 --- a/src/main/java/org/KaiFlo/SolarCell/Components/EnergyStorage/Implementations/EnergyStorageComponent.java +++ b/src/main/java/org/KaiFlo/SolarCell/Components/EnergyStorage/Implementations/EnergyStorageComponent.java @@ -11,7 +11,9 @@ import org.KaiFlo.SolarCell.Components.EnergyStorage.IEnergyStorage; import org.KaiFlo.SolarCell.SolarCellPlugin; import org.checkerframework.checker.nullness.compatqual.NullableDecl; -import static org.KaiFlo.SolarCell.Helpers.BlockHelper.LOGGER; +import java.util.Arrays; + +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.HyLogger; public class EnergyStorageComponent implements Component, IEnergyStorage { public static final BuilderCodec CODEC = BuilderCodec.builder(EnergyStorageComponent.class, EnergyStorageComponent::new) @@ -100,6 +102,12 @@ public class EnergyStorageComponent implements Component, IEnergySto public long extractEnergy(long requiredEnergy) { var extractedEnergy = Math.min(currentEnergyAmount, Math.min(requiredEnergy, extractEnergyPerTick)); currentEnergyAmount -= extractedEnergy; + if (extractedEnergy >=1000){ + HyLogger.atInfo().log("Extracted Energy: " + extractedEnergy + " now at " + currentEnergyAmount); + for (StackTraceElement element : Arrays.stream(Thread.currentThread().getStackTrace()).limit(7).toList()) { + HyLogger.atInfo().log(String.valueOf(element)); + } + } return extractedEnergy; } @@ -107,6 +115,7 @@ public class EnergyStorageComponent implements Component, IEnergySto public long receiveEnergy(long inputEnergy) { var receivedEnergy = Math.min(maxCapacity - currentEnergyAmount, Math.min(inputEnergy, receiveEnergyPerTick)); currentEnergyAmount += receivedEnergy; +// HyLogger.atInfo().log("Received Energy: " + receivedEnergy + " now at " + currentEnergyAmount); return receivedEnergy; } @@ -124,7 +133,7 @@ public class EnergyStorageComponent implements Component, IEnergySto try { super.clone(); } catch (CloneNotSupportedException e) { - LOGGER.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); + HyLogger.atWarning().log("Cloning of " + this.getClass().getName() + " failed."); } return new EnergyStorageComponent().copyFrom(this); } diff --git a/src/main/java/org/KaiFlo/SolarCell/Helpers/BlockHelper.java b/src/main/java/org/KaiFlo/SolarCell/Helpers/BlockHelper.java index 1b53d95..bec729d 100644 --- a/src/main/java/org/KaiFlo/SolarCell/Helpers/BlockHelper.java +++ b/src/main/java/org/KaiFlo/SolarCell/Helpers/BlockHelper.java @@ -5,47 +5,98 @@ import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.math.util.ChunkUtil; import com.hypixel.hytale.server.core.modules.block.BlockModule; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; import org.checkerframework.checker.nullness.compatqual.NonNullDecl; public class BlockHelper { - public static final HytaleLogger LOGGER = HytaleLogger.getLogger(); + public static final HytaleLogger HyLogger = HytaleLogger.getLogger(); public static void executeForCubeAround(int x, int y, int z, int size, boolean own, Callback callback) { for (int xOffset = 0; xOffset < size; xOffset++) { - for (int yOffset = 0; yOffset commandBuffer, + ChunkSafeCallback chunkSafeCallback + ) { + int halfSize = size / 2; + + for (int xOffset = -halfSize; xOffset <= halfSize; xOffset++) { + for (int yOffset = -halfSize; yOffset <= halfSize; yOffset++) { + for (int zOffset = -halfSize; zOffset <= halfSize; zOffset++) { + + int xPos = centerX + xOffset; + int yPos = centerY + yOffset; + int zPos = centerZ + zOffset; + + if (!includeCenter && xPos == centerX && yPos == centerY && zPos == centerZ) { + continue; + } + + int chunkX = Math.floorDiv(xPos, 32); + int chunkZ = Math.floorDiv(zPos, 32); + + int localX = Math.floorMod(xPos, 32); + int localZ = Math.floorMod(zPos, 32); + + WorldChunk targetChunk = world.getChunk(ChunkUtil.indexChunk(chunkX, chunkZ)); + if (targetChunk == null) continue; + + var blockComponentChunk = commandBuffer.getComponent( + targetChunk.getReference(), + BlockComponentChunk.getComponentType() + ); + if (blockComponentChunk == null) continue; + + int index = ChunkUtil.indexBlockInColumn(localX, yPos, localZ); + var targetRef = blockComponentChunk.getEntityReference(index); + if (targetRef == null) continue; + + chunkSafeCallback.accept(xPos, yPos, zPos, targetRef, blockComponentChunk, targetChunk); + } + } + } + } public interface Callback { void accept(int x, int y, int z); } + public interface ChunkSafeCallback { + + void accept(int x, int y, int z, Ref targetRef, BlockComponentChunk blockComponentChunk, WorldChunk targetChunk); + } public static void setBlockRefTicking(Ref blockRef, @NonNullDecl CommandBuffer commandBuffer) { BlockModule.BlockStateInfo blockInfo = commandBuffer.getComponent(blockRef, BlockModule.BlockStateInfo.getComponentType()); - if(blockInfo == null) return; + if (blockInfo == null) return; WorldChunk worldChunk = commandBuffer.getComponent(blockInfo.getChunkRef(), WorldChunk.getComponentType()); - if(worldChunk == null) return; + if (worldChunk == null) return; int x = ChunkUtil.xFromBlockInColumn(blockInfo.getIndex()); int y = ChunkUtil.yFromBlockInColumn(blockInfo.getIndex()); int z = ChunkUtil.zFromBlockInColumn(blockInfo.getIndex()); worldChunk.setTicking(x, y, z, true); - HytaleLogger.getLogger().atInfo().log(String.valueOf(worldChunk.isTicking(x, y, z))); } } diff --git a/src/main/java/org/KaiFlo/SolarCell/Helpers/ComponentHelper.java b/src/main/java/org/KaiFlo/SolarCell/Helpers/ComponentHelper.java new file mode 100644 index 0000000..3ef3247 --- /dev/null +++ b/src/main/java/org/KaiFlo/SolarCell/Helpers/ComponentHelper.java @@ -0,0 +1,16 @@ +package org.KaiFlo.SolarCell.Helpers; + +import com.hypixel.hytale.component.Component; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; + +import java.util.List; +import java.util.Optional; + +public class ComponentHelper { + public static Optional getComponentOfType(List> components, Class type){ + return components.stream() + .filter(x -> x.getClass() == type) + .map(type::cast) + .findFirst(); + } +} diff --git a/src/main/java/org/KaiFlo/SolarCell/SolarCellPlugin.java b/src/main/java/org/KaiFlo/SolarCell/SolarCellPlugin.java index bd45766..92d2f49 100644 --- a/src/main/java/org/KaiFlo/SolarCell/SolarCellPlugin.java +++ b/src/main/java/org/KaiFlo/SolarCell/SolarCellPlugin.java @@ -10,9 +10,13 @@ import org.KaiFlo.SolarCell.Components.EnergyConsumer.Implementations.EnergyCons import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; import org.KaiFlo.SolarCell.Systems.EnergySource.EnergySourceInitializerSystem; +import org.KaiFlo.SolarCell.Systems.EnergySource.TickingImplementations.SolarCellSourceTicking; +import org.KaiFlo.SolarCell.Systems.EnergyStorage.EnergyStorageInitializerSystem; +import org.KaiFlo.SolarCell.Systems.EnergyStorage.TickingImplementations.BatteryStorageTicking; import org.KaiFlo.SolarCell.Systems.EnergyTickingSystem; import javax.annotation.Nonnull; +import java.util.List; public class SolarCellPlugin extends JavaPlugin { @@ -44,8 +48,13 @@ public class SolarCellPlugin extends JavaPlugin { this.getCommandRegistry().registerCommand(new ExampleCommand(this.getName(), this.getManifest().getVersion().toString())); + var energyTickingSystem = new EnergyTickingSystem() + .withTickingSystemForComponentTypes(List.of(energyStorageComponentType), new BatteryStorageTicking()) + .withTickingSystemForComponentTypes(List.of(energySourceComponentType,energyStorageComponentType), new SolarCellSourceTicking()); + this.getChunkStoreRegistry().registerSystem(new EnergySourceInitializerSystem()); - this.getChunkStoreRegistry().registerSystem(new EnergyTickingSystem()); + this.getChunkStoreRegistry().registerSystem(new EnergyStorageInitializerSystem()); + this.getChunkStoreRegistry().registerSystem(energyTickingSystem); } diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/IEnergySourceTicking.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/IEnergySourceTicking.java deleted file mode 100644 index 7ca7ba9..0000000 --- a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/IEnergySourceTicking.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.KaiFlo.SolarCell.Systems.EnergySource; - -import com.hypixel.hytale.component.CommandBuffer; -import com.hypixel.hytale.protocol.Vector3i; -import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; -import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; -import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; -import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; - -public interface IEnergySourceTicking{ - void accept (EnergySourceComponent thisEnergySource, EnergyStorageComponent thisEnergyStorage, Vector3i globalPosition, BlockComponentChunk blockComponentChunk, CommandBuffer commandBuffer); -} diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/SolarCellSourceTicking.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/SolarCellSourceTicking.java deleted file mode 100644 index 9aad8ae..0000000 --- a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/SolarCellSourceTicking.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.KaiFlo.SolarCell.Systems.EnergySource; - -import com.hypixel.hytale.component.CommandBuffer; -import com.hypixel.hytale.math.util.ChunkUtil; -import com.hypixel.hytale.protocol.Vector3i; -import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; -import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; -import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; -import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; -import org.KaiFlo.SolarCell.Helpers.BlockHelper; - -import static org.KaiFlo.SolarCell.Helpers.BlockHelper.LOGGER; - -public class SolarCellSourceTicking implements IEnergySourceTicking{ - @Override - public void accept(EnergySourceComponent thisEnergySource, EnergyStorageComponent thisEnergyStorage, Vector3i globalPosition, BlockComponentChunk blockComponentChunk, CommandBuffer commandBuffer){ - - BlockHelper.executeForCubeAround(globalPosition.x, globalPosition.y, globalPosition.z, 5, false, (x, y, z) -> { - var index = ChunkUtil.indexBlockInColumn(x, y, z); - var targetRef = blockComponentChunk.getEntityReference(index); - if (targetRef == null) return; - var targetEnergySource = commandBuffer.getComponent(targetRef, EnergySourceComponent.getComponentType()); - var targetEnergyStorage = commandBuffer.getComponent(targetRef, EnergyStorageComponent.getComponentType()); - if (targetEnergySource == null || targetEnergyStorage == null) return; - - var energy = targetEnergyStorage.extractEnergy(targetEnergySource.getGeneratesPerTick()); - var inserted = thisEnergyStorage.receiveEnergy(energy); - LOGGER.atInfo().log("Inserted " + inserted + "/" + energy + " |" + targetEnergyStorage.getCurrentEnergyAmount() + "| into storage" + - " at Block " + globalPosition.x + ", " + globalPosition.y + ", " + globalPosition.z + ", " + - thisEnergyStorage.getCurrentEnergyAmount() + "/" + thisEnergyStorage.getMaxCapacity()); - }); - } -} diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/TickingImplementations/SolarCellSourceTicking.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/TickingImplementations/SolarCellSourceTicking.java new file mode 100644 index 0000000..76b6bf8 --- /dev/null +++ b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergySource/TickingImplementations/SolarCellSourceTicking.java @@ -0,0 +1,33 @@ +package org.KaiFlo.SolarCell.Systems.EnergySource.TickingImplementations; + +import com.hypixel.hytale.component.Archetype; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Component; +import com.hypixel.hytale.protocol.Vector3i; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; +import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; +import org.KaiFlo.SolarCell.Systems.ITickingSystem; + +import java.util.List; + +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.HyLogger; +import static org.KaiFlo.SolarCell.Helpers.ComponentHelper.getComponentOfType; + +public class SolarCellSourceTicking implements ITickingSystem { + + @Override + public void accept(List> foundComponents, Archetype archetype, Vector3i globalPosition, BlockComponentChunk blockComponentChunk, CommandBuffer commandBuffer, World world) { + var energyStorage = getComponentOfType(foundComponents, EnergyStorageComponent.class).orElse(null); + if (energyStorage == null) return; + var energySource = getComponentOfType(foundComponents, EnergySourceComponent.class).orElse(null); + if (energySource == null) return; + var received = energyStorage.receiveEnergy(energySource.getGeneratesPerTick()); + if (received!= 0){ + HyLogger.atInfo().log("Block at " + globalPosition.x+", "+ globalPosition.y+", " +globalPosition.z+" received " + received + " Energy, now at "+energyStorage.getCurrentEnergyAmount()); + } + } + +} diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/EnergyStorageInitializerSystem.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/EnergyStorageInitializerSystem.java new file mode 100644 index 0000000..cac43c8 --- /dev/null +++ b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/EnergyStorageInitializerSystem.java @@ -0,0 +1,31 @@ +package org.KaiFlo.SolarCell.Systems.EnergyStorage; + +import com.hypixel.hytale.component.*; +import com.hypixel.hytale.component.query.Query; +import com.hypixel.hytale.component.system.RefSystem; +import com.hypixel.hytale.server.core.modules.block.BlockModule; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; +import org.checkerframework.checker.nullness.compatqual.NonNullDecl; +import org.checkerframework.checker.nullness.compatqual.NullableDecl; + +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.setBlockRefTicking; + +public class EnergyStorageInitializerSystem extends RefSystem { + @Override + public void onEntityAdded(@NonNullDecl Ref ref, @NonNullDecl AddReason addReason, @NonNullDecl Store store, @NonNullDecl CommandBuffer commandBuffer) { + setBlockRefTicking(ref, commandBuffer); + } + + + @Override + public void onEntityRemove(@NonNullDecl Ref ref, @NonNullDecl RemoveReason removeReason, @NonNullDecl Store store, @NonNullDecl CommandBuffer commandBuffer) { + //Nothing to do yet + } + + @NullableDecl + @Override + public Query getQuery() { + return Query.and(EnergyStorageComponent.getComponentType(), BlockModule.BlockStateInfo.getComponentType()); + } +} diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/TickingImplementations/BatteryStorageTicking.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/TickingImplementations/BatteryStorageTicking.java new file mode 100644 index 0000000..3927506 --- /dev/null +++ b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyStorage/TickingImplementations/BatteryStorageTicking.java @@ -0,0 +1,54 @@ +package org.KaiFlo.SolarCell.Systems.EnergyStorage.TickingImplementations; + +import com.hypixel.hytale.component.Archetype; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Component; +import com.hypixel.hytale.protocol.Vector3i; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; +import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; +import org.KaiFlo.SolarCell.Systems.ITickingSystem; + +import java.util.List; + +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.HyLogger; +import static org.KaiFlo.SolarCell.Helpers.BlockHelper.executeForCubeAroundChunkSafe; +import static org.KaiFlo.SolarCell.Helpers.ComponentHelper.getComponentOfType; + +public class BatteryStorageTicking implements ITickingSystem { + + @Override + public void accept(List> foundComponents, Archetype archetype, Vector3i globalPosition, BlockComponentChunk blockComponentChunk, CommandBuffer commandBuffer, World world) { + var energyStorage = getComponentOfType(foundComponents, EnergyStorageComponent.class).orElse(null); + if (energyStorage == null) return; + var energySourceComponent = getComponentOfType(foundComponents, EnergySourceComponent.class).orElse(null); + if (energySourceComponent != null) return; + if (energyStorage.getCurrentEnergyAmount() >= energyStorage.getMaxCapacity()) { + return; + } + executeForCubeAroundChunkSafe(globalPosition.x, globalPosition.y, globalPosition.z, 5, false, world, commandBuffer, + (x, y, z, targetRef, blockCompChunk, targetChunk) -> { + + var targetEnergyStorage = commandBuffer.getComponent(targetRef, EnergyStorageComponent.getComponentType()); + if (targetEnergyStorage == null) return; + if (targetEnergyStorage.getCurrentEnergyAmount() < energyStorage.getCurrentEnergyAmount()) return; + + long energy = targetEnergyStorage.extractEnergy(Math.min(energyStorage.getMaxCapacity()-energyStorage.getCurrentEnergyAmount(), + Math.min( + targetEnergyStorage.getExtractEnergyPerTick(), + energyStorage.getReceiveEnergyPerTick() + ))); + long inserted = energyStorage.receiveEnergy(energy); + + if (inserted != 0 && energyStorage.getCurrentEnergyAmount() != energyStorage.getMaxCapacity()) { + HyLogger.atInfo().log("Inserted " + inserted + "/" + energy + + " |" + targetEnergyStorage.getCurrentEnergyAmount() + "| into storage" + + " at Block " + globalPosition.x + ", " + globalPosition.y + ", " + globalPosition.z + ", " + + energyStorage.getCurrentEnergyAmount() + "/" + energyStorage.getMaxCapacity()); + } + } + ); + } +} diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyTickingSystem.java b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyTickingSystem.java index 9176f38..8b24a4b 100644 --- a/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyTickingSystem.java +++ b/src/main/java/org/KaiFlo/SolarCell/Systems/EnergyTickingSystem.java @@ -1,8 +1,6 @@ package org.KaiFlo.SolarCell.Systems; -import com.hypixel.hytale.component.ArchetypeChunk; -import com.hypixel.hytale.component.CommandBuffer; -import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.component.*; import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.system.tick.EntityTickingSystem; import com.hypixel.hytale.math.util.ChunkUtil; @@ -13,52 +11,62 @@ import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk; import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection; import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection; import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; -import org.KaiFlo.SolarCell.Components.EnergyConsumer.Implementations.EnergyConsumerComponent; -import org.KaiFlo.SolarCell.Components.EnergySource.Implementations.EnergySourceComponent; -import org.KaiFlo.SolarCell.Components.EnergyStorage.Implementations.EnergyStorageComponent; -import org.KaiFlo.SolarCell.Systems.EnergySource.IEnergySourceTicking; -import org.KaiFlo.SolarCell.Systems.EnergySource.SolarCellSourceTicking; import org.checkerframework.checker.nullness.compatqual.NonNullDecl; import org.checkerframework.checker.nullness.compatqual.NullableDecl; -import java.util.List; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; public class EnergyTickingSystem extends EntityTickingSystem { - private final List energySourceTicking = List.of(new SolarCellSourceTicking()); + + private final Map>, ITickingSystem> componentsToTickingSystem = new HashMap<>(); + @Override - public void tick(float v, int i, @NonNullDecl ArchetypeChunk archetypeChunk, @NonNullDecl Store store, @NonNullDecl CommandBuffer commandBuffer) { - var blockSection = archetypeChunk.getComponent(i, BlockSection.getComponentType()); + public void tick(float v, int archetypeIndex, @NonNullDecl ArchetypeChunk archetypeChunk, @NonNullDecl Store store, @NonNullDecl CommandBuffer commandBuffer) { + + var blockSection = archetypeChunk.getComponent(archetypeIndex, BlockSection.getComponentType()); if (blockSection == null || blockSection.getTickingBlocksCount() != 0) return; - var chunkSection = archetypeChunk.getComponent(i, ChunkSection.getComponentType()); + var chunkSection = archetypeChunk.getComponent(archetypeIndex, ChunkSection.getComponentType()); if (chunkSection == null) return; var blockComponentChunk = commandBuffer.getComponent(chunkSection.getChunkColumnReference(), BlockComponentChunk.getComponentType()); var worldChunk = commandBuffer.getComponent(chunkSection.getChunkColumnReference(), WorldChunk.getComponentType()); if (blockComponentChunk == null || worldChunk == null) return; - blockSection.forEachTicking(blockComponentChunk, commandBuffer, chunkSection.getY(), - (blockCompChunk, _, localX, localY, localZ, _) -> { - var blockRef = blockCompChunk.getEntityReference(ChunkUtil.indexBlockInColumn(localX, localY, localZ)); - if (blockRef == null) return BlockTickStrategy.IGNORED; + var entrySet = componentsToTickingSystem.entrySet(); + var foundComponentTypes = new ArrayList>(); - int globalX = localX + (worldChunk.getX() * 32); - int globalZ = localZ + (worldChunk.getZ() * 32); - var globalPosition = new Vector3i(globalX, localY, globalZ); + blockSection.forEachTicking(blockComponentChunk, commandBuffer, chunkSection.getY(), (blockCompChunk, _, localX, localY, localZ, _) -> { + var blockRef = blockCompChunk.getEntityReference(ChunkUtil.indexBlockInColumn(localX, localY, localZ)); + if (blockRef == null) return BlockTickStrategy.IGNORED; - var energySourceComponent = commandBuffer.getComponent(blockRef, EnergySourceComponent.getComponentType()); - var energyConsumerComponent = commandBuffer.getComponent(blockRef, EnergyConsumerComponent.getComponentType()); - var energyStorageComponent = commandBuffer.getComponent(blockRef, EnergyStorageComponent.getComponentType()); - - if (energySourceComponent != null && energyStorageComponent != null){ - energySourceTicking.forEach(energySourceTicking -> energySourceTicking.accept(energySourceComponent, energyStorageComponent,globalPosition,blockCompChunk,commandBuffer)); - return BlockTickStrategy.CONTINUE; - } + int globalX = localX + (worldChunk.getX() * 32); + int globalZ = localZ + (worldChunk.getZ() * 32); + var globalPosition = new Vector3i(globalX, localY, globalZ); - return BlockTickStrategy.IGNORED; + var archetype = commandBuffer.getArchetype(blockRef); + + foundComponentTypes.clear(); + var foundComponents = new ArrayList>(); + for (int i = 0; i < archetype.length(); i++) { + var type = archetype.get(i); + if (type == null) continue; + foundComponentTypes.add(type); + foundComponents.add(commandBuffer.getComponent(blockRef, type)); + } + + AtomicBoolean hasAny = new AtomicBoolean(false); + entrySet.stream() + .filter(entry -> foundComponentTypes.containsAll(entry.getKey())).map(Map.Entry::getValue) + .forEach(tickingSystem -> { + hasAny.set(true); + tickingSystem.accept(foundComponents, archetype, globalPosition, blockCompChunk, commandBuffer, worldChunk.getWorld()); }); + return hasAny.get() ? BlockTickStrategy.CONTINUE : BlockTickStrategy.IGNORED; + }); } @@ -67,4 +75,9 @@ public class EnergyTickingSystem extends EntityTickingSystem { public Query getQuery() { return Query.and(BlockSection.getComponentType(), ChunkSection.getComponentType()); } + + public EnergyTickingSystem withTickingSystemForComponentTypes(List> componentTypes, ITickingSystem tickingSystem) { + componentsToTickingSystem.put(componentTypes, tickingSystem); + return this; + } } diff --git a/src/main/java/org/KaiFlo/SolarCell/Systems/ITickingSystem.java b/src/main/java/org/KaiFlo/SolarCell/Systems/ITickingSystem.java new file mode 100644 index 0000000..3a766a3 --- /dev/null +++ b/src/main/java/org/KaiFlo/SolarCell/Systems/ITickingSystem.java @@ -0,0 +1,16 @@ +package org.KaiFlo.SolarCell.Systems; + +import com.hypixel.hytale.component.Archetype; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Component; +import com.hypixel.hytale.protocol.Vector3i; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; + +import java.util.List; + +public interface ITickingSystem { + + void accept(List> foundComponents, Archetype archetype, Vector3i globalPosition, BlockComponentChunk blockComponentChunk, CommandBuffer commandBuffer, World world); +} diff --git a/src/main/resources/Server/Item/Items/EnergyStorage.json b/src/main/resources/Server/Item/Items/EnergyStorage.json index f85cef7..a1805d5 100644 --- a/src/main/resources/Server/Item/Items/EnergyStorage.json +++ b/src/main/resources/Server/Item/Items/EnergyStorage.json @@ -18,11 +18,11 @@ "BlockType": { "BlockEntity": { "Components": { - "EnergyStorageComponent": { - "EnergyStored": 5, - "MaxEnergy": 80000, - "MaxReceive": 1000, - "MaxExtract": 1000 + "EnergyStorage": { + "MaxCapacity": 10000, + "ExtractEnergyPerTick": 1000, + "ReceiveEnergyPerTick": 1000, + "CurrentEnergyAmount": 100 } } }, diff --git a/src/main/resources/Server/Item/Items/SolarCell.json b/src/main/resources/Server/Item/Items/SolarCell.json index f3b46d8..5990bef 100644 --- a/src/main/resources/Server/Item/Items/SolarCell.json +++ b/src/main/resources/Server/Item/Items/SolarCell.json @@ -18,12 +18,15 @@ "BlockType": { "BlockEntity": { "Components": { - "SolarCell": {}, - "EnergyStorageComponent": { - "EnergyStored": 5, - "MaxEnergy": 80000, - "MaxReceive": 1000, - "MaxExtract": 1000 + "EnergyStorage": { + "MaxCapacity": 10000, + "ExtractEnergyPerTick": 100, + "ReceiveEnergyPerTick": 1000, + "CurrentEnergyAmount": 0 + }, + "EnergySource": { + "EnergyCapacity": -1, + "GeneratesPerTick": 1000 } } },