148 lines
4.7 KiB
Java
148 lines
4.7 KiB
Java
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;
|
|
import net.minecraft.nbt.IntArrayTag;
|
|
import net.minecraft.server.world.ServerWorld;
|
|
import net.minecraft.util.Tickable;
|
|
import net.minecraft.util.math.Vec3d;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntity implements Tickable {
|
|
private class SelfProvider implements EnergyProvider {
|
|
@Override
|
|
public void addPropagatedAction(Action.PropagatedAction action) {
|
|
pendingActionsFromSelf.add(action);
|
|
}
|
|
|
|
@Override
|
|
public boolean isNetwork(int network) {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isWithinDistance(Vec3d pos) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public EnergyReceiverBlockEntity(BlockEntityType<?> type) {
|
|
super(type);
|
|
}
|
|
|
|
private final List<Action.PropagatedAction> pendingActions = new ArrayList<>();
|
|
private final List<Action.PropagatedAction> pendingActionsFromSelf = new ArrayList<>();
|
|
private final EnergyProvider selfProvider = new SelfProvider();
|
|
private final List<EnergyProvider> providers = new ArrayList<>();
|
|
private final List<Integer> networks = new ArrayList<>();
|
|
|
|
private long totalCost = 0;
|
|
|
|
protected void propagateAction(Action.PropagatedAction action) {
|
|
totalCost = totalCost + action.amountOwed();
|
|
action.expandPayments(providers.size());
|
|
pendingActions.add(action);
|
|
}
|
|
|
|
protected void addAction(Action action) {
|
|
propagateAction(new Action.PropagatedActionImpl(action, getWorld(), getPos(), getCachedState().getBlock()));
|
|
}
|
|
|
|
@Override
|
|
public void serverTick() {
|
|
if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) {
|
|
// Every Action Must Be Paid At Least Once For a Failure State To Occur
|
|
for (Action.PropagatedAction action : pendingActionsFromSelf) {
|
|
action.pay(0);
|
|
}
|
|
pendingActionsFromSelf.clear();
|
|
|
|
ServerWorld world = (ServerWorld) getWorld();
|
|
NetworkComponent component = NetworkComponent.getInstance(world);
|
|
|
|
providers.clear();
|
|
// At Least One Energy Provider Is Always Required
|
|
providers.add(selfProvider);
|
|
for (int network : networks) {
|
|
List<EnergyProvider> potentialProviders = component.getSource(world, network);
|
|
for (EnergyProvider provider : potentialProviders) {
|
|
Vec3d pos = new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d);
|
|
if (provider.isWithinDistance(pos)) {
|
|
providers.add(provider);
|
|
}
|
|
}
|
|
}
|
|
|
|
totalCost = 0;
|
|
pendingActions.clear();
|
|
tickEnergy();
|
|
|
|
super.serverTick();
|
|
|
|
for (Action.PropagatedAction action : pendingActions) {
|
|
for (EnergyProvider provider : providers) {
|
|
provider.addPropagatedAction(action);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public long getTotalCost() {
|
|
return totalCost;
|
|
}
|
|
|
|
@Override
|
|
protected void handlePropagatedAction(Action.PropagatedAction action) {
|
|
// Propagate Action To Energy Providers
|
|
if (isEnergyProviderActive()) {
|
|
propagateAction(action);
|
|
} else {
|
|
action.pay(0);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public CompoundTag toTag(CompoundTag tag) {
|
|
super.toTag(tag);
|
|
tag.put("Networks", new IntArrayTag(networks));
|
|
return tag;
|
|
}
|
|
|
|
@Override
|
|
public void fromTag(BlockState state, CompoundTag tag) {
|
|
super.fromTag(state, tag);
|
|
int[] networksArray = tag.getIntArray("Networks");
|
|
networks.clear();
|
|
for (int network : networksArray) {
|
|
networks.add(network);
|
|
}
|
|
}
|
|
|
|
protected boolean isEnergyProviderActive() {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
protected abstract void tickEnergy();
|
|
|
|
public void toggle(int network) {
|
|
if (contains(network)) {
|
|
networks.removeAll(Collections.singletonList(network));
|
|
} else {
|
|
networks.add(network);
|
|
}
|
|
markDirty();
|
|
}
|
|
|
|
public boolean contains(int network) {
|
|
return networks.contains(network);
|
|
}
|
|
}
|