This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
EnergonRelics/src/main/java/com/thebrokenrail/energonrelics/api/block/entity/core/EnergyReceiverBlockEntity.java

169 lines
4.9 KiB
Java

package com.thebrokenrail.energonrelics.api.block.entity.core;
import com.thebrokenrail.energonrelics.api.energy.Action;
import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.api.energy.tick.EnergyTickable;
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.math.Vec3d;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Block Entity That Receives Energy
*/
public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntity {
public EnergyReceiverBlockEntity(BlockEntityType<?> type) {
super(type);
}
private final List<EnergyProviderBlockEntity> providers = new ArrayList<>();
private final List<Integer> networks = new ArrayList<>();
private long totalCost = 0;
private long previousTotalCost = 0;
private final List<Action.PropagatedAction> sent = new ArrayList<>();
/**
* If The Specified Action Has Been Sent By This Block this Tick
* @param action Action
* @return If It Was Sent
*/
protected final boolean hasSent(Action.PropagatedAction action) {
return sent.contains(action);
}
/**
* Propagate Action To The Network's Energy Providers
* @param action Propagated Action
*/
protected final void propagateAction(Action.PropagatedAction action) {
sent.add(action);
totalCost = totalCost + action.amountOwed();
if (providers.size() > 0) {
action.expandPayments(providers.size());
for (EnergyProviderBlockEntity provider : providers) {
if (action.amountOwed() > 0) {
provider.addPropagatedAction(action);
} else {
action.pay(0);
}
}
} else {
action.pay(0);
}
}
/**
* Convert Action To A Propagated Action And Then Propagate It
* @param action Action
*/
protected final void addAction(Action action) {
propagateAction(new Action.PropagatedActionImpl(action, getWorld(), getPos(), getCachedState()));
}
@Override
public final List<EnergyTickable> startTick() {
sent.clear();
List<EnergyTickable> list = new ArrayList<>(super.startTick());
ServerWorld world = (ServerWorld) getWorld();
assert world != null;
NetworkComponent component = NetworkComponent.getInstance(world);
providers.clear();
for (int network : networks) {
List<EnergyProviderBlockEntity> potentialProviders = component.getSources(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)) {
providers.add(provider);
}
}
}
}
previousTotalCost = totalCost;
totalCost = 0;
list.addAll(providers);
return list;
}
@Override
public final void logicTick() {
super.logicTick();
assert getWorld() != null;
getWorld().getProfiler().push("energyTick");
energyTick();
getWorld().getProfiler().pop();
}
/**
* Get Total Cost In Energon
* @return Cost
*/
@ApiStatus.Internal
public final long getTotalCost() {
return previousTotalCost;
}
@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);
}
}
/**
* Create And Propagate Actions
*/
@ApiStatus.OverrideOnly
protected abstract void energyTick();
/**
* Toggle If This Is In The Specified Network
* @param network Network ID
*/
@ApiStatus.Internal
public void toggle(int network) {
if (contains(network)) {
networks.removeAll(Collections.singletonList(network));
} else {
networks.add(network);
}
markDirty();
}
/**
* Check If The Specified Network Contains This Block
* @param network Network ID
* @return If It Contains This Block
*/
@ApiStatus.Internal
public boolean contains(int network) {
return networks.contains(network);
}
}