EnergonRelics/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java

148 lines
4.4 KiB
Java

package com.thebrokenrail.energonrelics.energy.core;
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 net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProvider, BlockEntityClientSerializable, Tickable {
private final ArrayList<Action.PropagatedAction> pendingPropagatedActions = new ArrayList<>();
private static final List<EnergyProviderBlockEntity> scheduledTicks = new ArrayList<>();
public static void tickScheduled() {
Collections.shuffle(scheduledTicks);
for (EnergyProviderBlockEntity provider : scheduledTicks) {
provider.serverTick();
}
scheduledTicks.clear();
}
public EnergyProviderBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
public final void addPropagatedAction(Action.PropagatedAction action) {
if (isEnergyProvider()) {
pendingPropagatedActions.add(action);
} else {
throw new UnsupportedOperationException();
}
}
@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);
}
private ItemStack stack = ItemStack.EMPTY;
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
if (isEnergyProvider()) {
tag.put("NetworkChip", stack.toTag(new CompoundTag()));
}
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
if (isEnergyProvider()) {
stack = ItemStack.fromTag(tag.getCompound("NetworkChip"));
} else {
stack = ItemStack.EMPTY;
}
}
public boolean isEnergyProvider() {
return false;
}
protected void handlePropagatedAction(Action.PropagatedAction action) {
throw new UnsupportedOperationException();
}
private void tickPropagatedActions() {
if (isEnergyProvider()) {
for (Action.PropagatedAction action : pendingPropagatedActions) {
handlePropagatedAction(action);
}
NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld()));
List<BlockPos> sources = component.getSourcePos(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack));
if (!sources.contains(getPos())) {
takeStack();
}
}
pendingPropagatedActions.clear();
}
protected void serverTick() {
tickPropagatedActions();
}
@Override
public final void tick() {
if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) {
scheduledTicks.add(this);
}
}
public ItemStack takeStack() {
ItemStack newStack = stack.copy();
stack = ItemStack.EMPTY;
markDirty();
return newStack;
}
public void placeStack(ItemStack newStack) {
stack = newStack.copy();
markDirty();
}
public boolean hasStack() {
return !stack.isEmpty();
}
@Override
public void fromClientTag(CompoundTag compoundTag) {
fromTag(Blocks.AIR.getDefaultState(), compoundTag);
}
@Override
public CompoundTag toClientTag(CompoundTag compoundTag) {
return toTag(compoundTag);
}
@Override
public void markDirty() {
super.markDirty();
sync();
}
}