From a86581d91360e3277acc8668cd3eb003edd8e7e9 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Fri, 24 Jul 2020 13:25:50 -0400 Subject: [PATCH] Fix Energy System Bugs --- .../block/entity/LightningRodBlockEntity.java | 5 +- .../block/entity/SolarPanelBlockEntity.java | 6 +- .../reactor/ReactorControllerBlockEntity.java | 5 +- .../component/NetworkComponent.java | 10 ++-- .../core/EnergyProviderBlockEntity.java | 53 +++--------------- .../core/EnergyReceiverBlockEntity.java | 56 +++++++++---------- .../energy/core/util/EnergyProvider.java | 12 ---- .../energy/core/util/EnergyTicker.java | 38 +++++++++++++ .../energonrelics/mixin/MixinWorld.java | 4 +- 9 files changed, 90 insertions(+), 99 deletions(-) delete mode 100644 src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyTicker.java diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/LightningRodBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/LightningRodBlockEntity.java index c4fb66b..76b7bc9 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/entity/LightningRodBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/LightningRodBlockEntity.java @@ -11,6 +11,7 @@ import net.minecraft.entity.LightningEntity; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.LightType; +import java.util.List; import java.util.Objects; import java.util.Random; @@ -49,7 +50,7 @@ public class LightningRodBlockEntity extends EnergyProviderBlockEntity implement } @Override - protected void serverTick() { + public List startTick() { if (cooldown <= 0) { energy = 0; @@ -68,7 +69,7 @@ public class LightningRodBlockEntity extends EnergyProviderBlockEntity implement } else { cooldown--; } - super.serverTick(); + return super.startTick(); } @Override diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/SolarPanelBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/SolarPanelBlockEntity.java index c534802..dc7394d 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/entity/SolarPanelBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/SolarPanelBlockEntity.java @@ -1,11 +1,13 @@ package com.thebrokenrail.energonrelics.block.entity; import com.thebrokenrail.energonrelics.config.HardcodedConfig; +import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; import com.thebrokenrail.energonrelics.energy.helper.EnergyGeneratorBlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.math.Direction; import net.minecraft.world.LightType; +import java.util.List; import java.util.Objects; public class SolarPanelBlockEntity extends EnergyGeneratorBlockEntity { @@ -37,8 +39,8 @@ public class SolarPanelBlockEntity extends EnergyGeneratorBlockEntity { } @Override - protected void serverTick() { + public List startTick() { setEnergy(getDisplayEnergy()); - super.serverTick(); + return super.startTick(); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/reactor/ReactorControllerBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/reactor/ReactorControllerBlockEntity.java index f5efde6..4eb8c88 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/entity/reactor/ReactorControllerBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/reactor/ReactorControllerBlockEntity.java @@ -5,6 +5,7 @@ import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.block.battery.PassiveBatteryControllerBlock; import com.thebrokenrail.energonrelics.block.entity.battery.PassiveBatteryControllerBlockEntity; import com.thebrokenrail.energonrelics.block.reactor.ReactorControllerBlock; +import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; import com.thebrokenrail.energonrelics.energy.helper.EnergyGeneratorBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -32,7 +33,7 @@ public class ReactorControllerBlockEntity extends EnergyGeneratorBlockEntity { } @Override - protected void serverTick() { + public List startTick() { if (getCachedState().get(ReactorControllerBlock.POWERED)) { Reactor reactor = getReactor(); if (reactor != null && !reactor.core.isReacting()) { @@ -62,7 +63,7 @@ public class ReactorControllerBlockEntity extends EnergyGeneratorBlockEntity { } } setEnergy(getDisplayEnergy()); - super.serverTick(); + return super.startTick(); } @Override diff --git a/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java b/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java index 20571ba..dfda189 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java +++ b/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java @@ -1,7 +1,7 @@ package com.thebrokenrail.energonrelics.component; import com.thebrokenrail.energonrelics.EnergonRelics; -import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider; +import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; import com.thebrokenrail.energonrelics.util.BlockPosWithDimension; import net.minecraft.block.entity.BlockEntity; import net.minecraft.datafixer.NbtOps; @@ -112,18 +112,18 @@ public class NetworkComponent extends PersistentState { return entry.sources; } - public List getSource(World world, int id) { + public List getSource(World world, int id) { List sources = getSourcePos(id); List valid = new ArrayList<>(); Iterator iterator = sources.iterator(); - List providers = new ArrayList<>(); + List providers = new ArrayList<>(); boolean dirty = false; while (iterator.hasNext()) { BlockPosWithDimension pos = iterator.next(); if (!valid.contains(pos)) { BlockEntity entity = Objects.requireNonNull(Objects.requireNonNull(world.getServer()).getWorld(pos.dimension)).getBlockEntity(pos.pos); - if (entity instanceof EnergyProvider && ((EnergyProvider) entity).isNetwork(id)) { - providers.add((EnergyProvider) entity); + if (entity instanceof EnergyProviderBlockEntity && ((EnergyProviderBlockEntity) entity).isNetwork(id)) { + providers.add((EnergyProviderBlockEntity) entity); } else { iterator.remove(); dirty = true; diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java index d0cc03d..31b9afd 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java @@ -4,7 +4,7 @@ import com.thebrokenrail.energonrelics.config.HardcodedConfig; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.component.NetworkComponent; import com.thebrokenrail.energonrelics.energy.core.util.Action; -import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider; +import com.thebrokenrail.energonrelics.energy.core.util.EnergyTicker; import com.thebrokenrail.energonrelics.util.BlockPosWithDimension; import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; import net.minecraft.block.BlockState; @@ -25,43 +25,11 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProvider, BlockEntityClientSerializable, Tickable { - private static volatile boolean isTicking = false; - - private static final List scheduledTicks = new ArrayList<>(); - private static final List scheduledTicksNext = new ArrayList<>(); - - public static void tickScheduled() { - isTicking = true; - Collections.shuffle(scheduledTicks); - for (EnergyProviderBlockEntity provider : scheduledTicks) { - provider.serverTick(); - } - scheduledTicks.clear(); - isTicking = false; - for (EnergyProviderBlockEntity entity : scheduledTicksNext) { - entity.schedule(); - } - scheduledTicksNext.clear(); - } - - private void schedule() { - List list; - if (isTicking) { - list = scheduledTicksNext; - } else { - list = scheduledTicks; - } - if (!list.contains(this)) { - list.add(this); - } - } - +public class EnergyProviderBlockEntity extends BlockEntity implements BlockEntityClientSerializable, Tickable { public EnergyProviderBlockEntity(BlockEntityType type) { super(type); } - @Override public final void addPropagatedAction(Action.PropagatedAction action) { if (isEnergyProvider()) { if (!completedActions.contains(action)) { @@ -73,17 +41,14 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv } } - @Override public final boolean isNetwork(int network) { return isEnergyProvider() && EnergonRelics.NETWORK_CHIP_ITEM.getID(stack) == network; } - @Override public final boolean isWithinDistance(Vec3d pos) { return getPos().isWithinDistance(pos, HardcodedConfig.POWER_RANGE); } - @Override public RegistryKey getRegistryKey() { return Objects.requireNonNull(getWorld()).getRegistryKey(); } @@ -118,12 +83,13 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv protected void handlePropagatedAction(Action.PropagatedAction action) { if (!isEnergyProvider()) { throw new UnsupportedOperationException(); - } else { - schedule(); } } - private void tickPropagatedActions() { + public void logicTick() { + } + + public List startTick() { completedActions.clear(); if (isEnergyProvider()) { NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld())); @@ -132,16 +98,13 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv takeStack(getWorld()); } } - } - - protected void serverTick() { - tickPropagatedActions(); + return Collections.emptyList(); } @Override public final void tick() { if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) { - schedule(); + EnergyTicker.schedule(this); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java index 79124d9..0fb57c8 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java @@ -2,7 +2,6 @@ package com.thebrokenrail.energonrelics.energy.core; import com.thebrokenrail.energonrelics.component.NetworkComponent; import com.thebrokenrail.energonrelics.energy.core.util.Action; -import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.nbt.CompoundTag; @@ -20,16 +19,22 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit super(type); } - private final List pendingPropagatedActions = new ArrayList<>(); - private final List pendingActions = new ArrayList<>(); - private final List providers = new ArrayList<>(); + private final List providers = new ArrayList<>(); private final List networks = new ArrayList<>(); private long totalCost = 0; + private long previousTotalCost = 0; protected void propagateAction(Action.PropagatedAction action) { totalCost = totalCost + action.amountOwed(); - pendingActions.add(action); + if (providers.size() > 0) { + action.expandPayments(providers.size()); + for (EnergyProviderBlockEntity provider : providers) { + provider.addPropagatedAction(action); + } + } else { + action.pay(0); + } } protected void addAction(Action action) { @@ -37,15 +42,17 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit } @Override - public void serverTick() { + public List startTick() { + List list = new ArrayList<>(super.startTick()); + ServerWorld world = (ServerWorld) getWorld(); assert world != null; NetworkComponent component = NetworkComponent.getInstance(world); providers.clear(); for (int network : networks) { - List potentialProviders = component.getSource(world, network); - for (EnergyProvider provider : potentialProviders) { + List potentialProviders = component.getSource(world, network); + for (EnergyProviderBlockEntity provider : potentialProviders) { if (provider.getRegistryKey().equals(getWorld().getRegistryKey())) { Vec3d pos = new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d); if (provider.isWithinDistance(pos)) { @@ -55,31 +62,22 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit } } + previousTotalCost = totalCost; totalCost = 0; - pendingActions.clear(); + + list.addAll(providers); + + return list; + } + + @Override + public void logicTick() { + super.logicTick(); tickEnergy(); - - super.serverTick(); - - for (Action.PropagatedAction action : pendingPropagatedActions) { - propagateAction(action); - } - pendingPropagatedActions.clear(); - - for (Action.PropagatedAction action : pendingActions) { - if (providers.size() > 0) { - action.expandPayments(providers.size()); - for (EnergyProvider provider : providers) { - provider.addPropagatedAction(action); - } - } else { - action.pay(0); - } - } } public long getTotalCost() { - return totalCost; + return previousTotalCost; } @Override @@ -87,7 +85,7 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit super.handlePropagatedAction(action); // Propagate Action To Energy Providers if (isEnergyProviderActive()) { - pendingPropagatedActions.add(action); + propagateAction(action); } else { action.pay(0); } diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java deleted file mode 100644 index 3079e87..0000000 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.thebrokenrail.energonrelics.energy.core.util; - -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.registry.RegistryKey; -import net.minecraft.world.World; - -public interface EnergyProvider { - void addPropagatedAction(Action.PropagatedAction action); - boolean isNetwork(int network); - boolean isWithinDistance(Vec3d pos); - RegistryKey getRegistryKey(); -} diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyTicker.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyTicker.java new file mode 100644 index 0000000..0a63a42 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyTicker.java @@ -0,0 +1,38 @@ +package com.thebrokenrail.energonrelics.energy.core.util; + +import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class EnergyTicker { + private static final List scheduled = new ArrayList<>(); + + public static void schedule(EnergyProviderBlockEntity provider) { + scheduled.add(provider); + } + + public static void tick() { + List started = new ArrayList<>(); + + List temp = new ArrayList<>(scheduled); + List temp2 = new ArrayList<>(); + while (!temp.isEmpty()) { + for (EnergyProviderBlockEntity provider : temp) { + if (!started.contains(provider)) { + temp2.addAll(provider.startTick()); + started.add(provider); + } + } + temp.clear(); + temp.addAll(temp2); + temp2.clear(); + } + + Collections.shuffle(started); + for (EnergyProviderBlockEntity provider : started) { + provider.logicTick(); + } + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinWorld.java b/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinWorld.java index 94532dd..24b3892 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinWorld.java +++ b/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinWorld.java @@ -1,6 +1,6 @@ package com.thebrokenrail.energonrelics.mixin; -import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; +import com.thebrokenrail.energonrelics.energy.core.util.EnergyTicker; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -16,7 +16,7 @@ public abstract class MixinWorld { @Inject(at = @At("TAIL"), method = "tickBlockEntities") public void tickBlockEntities(CallbackInfo info) { if (!isClient()) { - EnergyProviderBlockEntity.tickScheduled(); + EnergyTicker.tick(); } } }