Skip to content

Commit

Permalink
feat: portable grid activeness and energy
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulvdberge committed Dec 30, 2023
1 parent 552910a commit 72f72c2
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage2.platform.api.configurationcard;

import java.util.Collections;
import java.util.List;

import net.minecraft.nbt.CompoundTag;
Expand All @@ -15,7 +16,11 @@ public interface ConfigurationCardTarget {

void readConfiguration(CompoundTag tag);

List<Item> getUpgradeItems();
default List<Item> getUpgradeItems() {
return Collections.emptyList();
}

boolean addUpgradeItem(Item upgradeItem);
default boolean addUpgradeItem(Item upgradeItem) {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.refinedmods.refinedstorage2.platform.common.storage.portablegrid;

import com.refinedmods.refinedstorage2.api.core.Action;
import com.refinedmods.refinedstorage2.api.grid.GridWatcher;
import com.refinedmods.refinedstorage2.api.grid.operations.GridExtractMode;
import com.refinedmods.refinedstorage2.api.grid.operations.GridInsertMode;
import com.refinedmods.refinedstorage2.api.grid.operations.GridOperations;
import com.refinedmods.refinedstorage2.api.network.energy.EnergyStorage;
import com.refinedmods.refinedstorage2.api.storage.Actor;
import com.refinedmods.refinedstorage2.api.storage.ExtractableStorage;
import com.refinedmods.refinedstorage2.api.storage.InMemoryStorageImpl;
Expand All @@ -15,21 +17,29 @@
import com.refinedmods.refinedstorage2.api.storage.TypedStorage;
import com.refinedmods.refinedstorage2.api.storage.channel.StorageChannelType;
import com.refinedmods.refinedstorage2.platform.api.PlatformApi;
import com.refinedmods.refinedstorage2.platform.api.configurationcard.ConfigurationCardTarget;
import com.refinedmods.refinedstorage2.platform.api.grid.Grid;
import com.refinedmods.refinedstorage2.platform.api.storage.channel.PlatformStorageChannelType;
import com.refinedmods.refinedstorage2.platform.api.support.energy.EnergyBlockEntity;
import com.refinedmods.refinedstorage2.platform.api.support.resource.ItemResource;
import com.refinedmods.refinedstorage2.platform.common.Platform;
import com.refinedmods.refinedstorage2.platform.common.content.BlockEntities;
import com.refinedmods.refinedstorage2.platform.common.content.ContentNames;
import com.refinedmods.refinedstorage2.platform.common.grid.AbstractGridContainerMenu;
import com.refinedmods.refinedstorage2.platform.common.storage.Disk;
import com.refinedmods.refinedstorage2.platform.common.storage.DiskInventory;
import com.refinedmods.refinedstorage2.platform.common.storage.DiskStateChangeListener;
import com.refinedmods.refinedstorage2.platform.common.support.RedstoneMode;
import com.refinedmods.refinedstorage2.platform.common.support.RedstoneModeSettings;
import com.refinedmods.refinedstorage2.platform.common.support.energy.BlockEntityEnergyStorage;
import com.refinedmods.refinedstorage2.platform.common.support.energy.CreativeEnergyStorage;
import com.refinedmods.refinedstorage2.platform.common.util.ContainerUtil;

import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

import com.google.common.util.concurrent.RateLimiter;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
Expand All @@ -45,26 +55,65 @@
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractPortableGridBlockEntity extends BlockEntity implements Grid, MenuProvider,
EnergyBlockEntity, ConfigurationCardTarget {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPortableGridBlockEntity.class);

public abstract class AbstractPortableGridBlockEntity extends BlockEntity implements Grid, MenuProvider {
private static final String TAG_DISK_INVENTORY = "inv";
private static final String TAG_DISKS = "disks";
private static final String TAG_STORED = "stored";
private static final String TAG_REDSTONE_MODE = "rm";

@Nullable
protected Disk disk;

private final DiskInventory diskInventory;
private final DiskStateChangeListener diskStateListener = new DiskStateChangeListener(this);
private final EnergyStorage energyStorage;
private final RateLimiter activenessChangeRateLimiter = RateLimiter.create(1);

private RedstoneMode redstoneMode = RedstoneMode.IGNORE;
@Nullable
private TypedStorage<?, StateTrackedStorage<?>> storage;

protected AbstractPortableGridBlockEntity(final PortableGridType type, final BlockPos pos, final BlockState state) {
super(getBlockEntityType(type), pos, state);
this.diskInventory = new DiskInventory(this::onDiskChanged, 1);
this.energyStorage = createEnergyStorage(type, this);
}

void updateDiskStateIfNecessaryInLevel() {
private static EnergyStorage createEnergyStorage(final PortableGridType type, final BlockEntity blockEntity) {
if (type == PortableGridType.CREATIVE) {
return CreativeEnergyStorage.INSTANCE;
}
return new BlockEntityEnergyStorage(
Platform.INSTANCE.getConfig().getController().getEnergyCapacity(), // TODO
blockEntity
);
}

void update(final BlockState state) {
diskStateListener.updateIfNecessary();
final boolean newActive = isGridActive();
final boolean activenessNeedsUpdate = state.getValue(PortableGridBlock.ACTIVE) != newActive;
if (activenessNeedsUpdate && activenessChangeRateLimiter.tryAcquire()) {
updateActivenessBlockState(state, newActive);
}
}

private void updateActivenessBlockState(final BlockState state, final boolean active) {
if (level != null) {
LOGGER.debug(
"Sending block update at {} due to activeness change: {} -> {}",
getBlockPos(),
state.getValue(PortableGridBlock.ACTIVE),
active
);
level.setBlockAndUpdate(getBlockPos(), state.setValue(PortableGridBlock.ACTIVE, active));
}
}

private void onDiskChanged(final int slot) {
Expand Down Expand Up @@ -111,9 +160,20 @@ public void load(final CompoundTag tag) {
if (tag.contains(TAG_DISK_INVENTORY)) {
ContainerUtil.read(tag.getCompound(TAG_DISK_INVENTORY), diskInventory);
}
if (tag.contains(TAG_STORED)) {
energyStorage.receive(tag.getLong(TAG_STORED), Action.EXECUTE);
}
readConfiguration(tag);
super.load(tag);
}

@Override
public void readConfiguration(final CompoundTag tag) {
if (tag.contains(TAG_REDSTONE_MODE)) {
redstoneMode = RedstoneModeSettings.getRedstoneMode(tag.getInt(TAG_REDSTONE_MODE));
}
}

private void fromClientTag(final CompoundTag tag) {
if (!tag.contains(TAG_DISKS)) {
return;
Expand All @@ -130,6 +190,13 @@ protected void onClientDriveStateUpdated() {
public void saveAdditional(final CompoundTag tag) {
super.saveAdditional(tag);
tag.put(TAG_DISK_INVENTORY, ContainerUtil.write(diskInventory));
tag.putLong(TAG_STORED, energyStorage.getStored());
writeConfiguration(tag);
}

@Override
public void writeConfiguration(final CompoundTag tag) {
tag.putInt(TAG_REDSTONE_MODE, RedstoneModeSettings.getRedstoneMode(redstoneMode));
}

@Override
Expand All @@ -140,12 +207,27 @@ public Packet<ClientGamePacketListener> getUpdatePacket() {
@Override
public CompoundTag getUpdateTag() {
final CompoundTag tag = new CompoundTag();
tag.put(TAG_DISKS, diskInventory.toSyncTag(idx -> getState()));
tag.put(TAG_DISKS, diskInventory.toSyncTag(idx -> getStorageState()));
return tag;
}

private StorageState getState() {
return storage != null ? storage.storage().getState() : StorageState.NONE;
public RedstoneMode getRedstoneMode() {
return redstoneMode;
}

public void setRedstoneMode(final RedstoneMode redstoneMode) {
this.redstoneMode = redstoneMode;
setChanged();
}

private StorageState getStorageState() {
if (storage == null) {
return StorageState.NONE;
}
if (!isGridActive()) {
return StorageState.INACTIVE;
}
return storage.storage().getState();
}

@Override
Expand All @@ -165,10 +247,12 @@ public Storage<ItemResource> getItemStorage() {

@Override
public boolean isGridActive() {
return energyStorage.getStored() > 0
&& level != null
&& redstoneMode.isActive(level.hasNeighborSignal(worldPosition));
// TODO: add energy component
// TODO: sync activeness to block state
// TODO: energy level in GUI
return true;
}

@Override
Expand Down Expand Up @@ -212,6 +296,11 @@ public SimpleContainer getDiskInventory() {
return diskInventory;
}

@Override
public EnergyStorage getEnergyStorage() {
return energyStorage;
}

private static BlockEntityType<AbstractPortableGridBlockEntity> getBlockEntityType(final PortableGridType type) {
return type == PortableGridType.CREATIVE
? BlockEntities.INSTANCE.getCreativePortableGrid()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@
import net.minecraft.world.MenuProvider;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;

public class PortableGridBlock extends AbstractDirectionalBlock<BiDirection> implements EntityBlock {
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");

private static final VoxelShape SHAPE_HORIZONTAL = box(0, 0, 0, 16, 13.2, 16);
private static final VoxelShape SHAPE_VERTICAL_SOUTH = box(0, 0, 0, 16, 16, 13.2);
private static final VoxelShape SHAPE_VERTICAL_NORTH = box(0, 0, 16 - 13.2, 16, 16, 16);
Expand All @@ -42,6 +47,17 @@ public PortableGridBlock(final PortableGridType type,
this.blockEntityFactory = factory;
}

@Override
protected BlockState getDefaultState() {
return super.getDefaultState().setValue(ACTIVE, false);
}

@Override
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
}

@Override
protected DirectionType<BiDirection> getDirectionType() {
return BiDirectionType.INSTANCE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public void tick(final Level level,
final BlockPos pos,
final BlockState state,
final AbstractPortableGridBlockEntity blockEntity) {
blockEntity.updateDiskStateIfNecessaryInLevel();
blockEntity.update(state);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.refinedmods.refinedstorage2.platform.api.storage.StorageContainerItem;
import com.refinedmods.refinedstorage2.platform.common.content.Menus;
import com.refinedmods.refinedstorage2.platform.common.grid.AbstractGridContainerMenu;
import com.refinedmods.refinedstorage2.platform.common.support.RedstoneMode;
import com.refinedmods.refinedstorage2.platform.common.support.containermenu.ClientProperty;
import com.refinedmods.refinedstorage2.platform.common.support.containermenu.PropertyTypes;
import com.refinedmods.refinedstorage2.platform.common.support.containermenu.ServerProperty;
import com.refinedmods.refinedstorage2.platform.common.support.containermenu.ValidatedSlot;

import net.minecraft.network.FriendlyByteBuf;
Expand All @@ -16,6 +20,7 @@ public PortableGridContainerMenu(final int syncId, final Inventory playerInvento
super(Menus.INSTANCE.getPortableGrid(), syncId, playerInventory, buf);
this.diskInventory = new SimpleContainer(1);
addSlots(0);
registerProperty(new ClientProperty<>(PropertyTypes.REDSTONE_MODE, RedstoneMode.IGNORE));
}

PortableGridContainerMenu(final int syncId,
Expand All @@ -24,6 +29,11 @@ public PortableGridContainerMenu(final int syncId, final Inventory playerInvento
super(Menus.INSTANCE.getPortableGrid(), syncId, playerInventory, portableGrid);
this.diskInventory = portableGrid.getDiskInventory();
addSlots(0);
registerProperty(new ServerProperty<>(
PropertyTypes.REDSTONE_MODE,
portableGrid::getRedstoneMode,
portableGrid::setRedstoneMode
));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
import com.refinedmods.refinedstorage2.platform.common.support.RedstoneMode;
import com.refinedmods.refinedstorage2.platform.common.support.RedstoneModeSettings;

import java.util.Collections;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;

import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;

Expand Down Expand Up @@ -71,16 +68,6 @@ public void readConfiguration(final CompoundTag tag) {
}
}

@Override
public List<Item> getUpgradeItems() {
return Collections.emptyList();
}

@Override
public boolean addUpgradeItem(final Item upgradeItem) {
return false;
}

public RedstoneMode getRedstoneMode() {
return redstoneMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public void emitBlockQuads(final BlockAndTintGetter blockView,
emitDiskQuads(blockView, state, pos, randomSupplier, context, disk);
}
}
inactiveModel.emitBlockQuads(blockView, state, pos, randomSupplier, context);
final boolean active = state.getValue(PortableGridBlock.ACTIVE);
(active ? activeModel : inactiveModel).emitBlockQuads(blockView, state, pos, randomSupplier, context);
context.popTransform();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ public List<BakedQuad> getQuads(@Nullable final BlockState state,
if (disk == null) {
return super.getQuads(state, side, randomSource);
}
return cache.getUnchecked(new CacheKey(side, direction, true, disk));
final boolean active = state.getValue(PortableGridBlock.ACTIVE);
return cache.getUnchecked(new CacheKey(side, direction, active, disk));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ private void notifyListener() {
@Override
public long extract(final T resource, final long amount, final Action action, final Actor actor) {
final long extracted = delegate.extract(resource, amount, action, actor);
// TODO: https://sonarcloud.io/component_measures?metric=new_coverage&selected=refinedmods_refinedstorage2%3
// Arefinedstorage2-storage-api%2Fsrc%2Fmain%2Fjava%2Fcom%2Frefinedmods%2Frefinedstorage2%2Fapi%2
// Fstorage%2FStateTrackedStorage.java&view=list&pullRequest=465&id=refinedmods_refinedstorage2
if (extracted > 0 && action == Action.EXECUTE) {
checkStateChanged();
}
Expand Down

0 comments on commit 72f72c2

Please sign in to comment.