Updates to the awareness block #55

Merged
BlakeRain merged 10 commits from BlakeRain/utamacraft:main into main 2024-01-23 14:41:55 +00:00
4 changed files with 154 additions and 18 deletions
Showing only changes of commit fc6070e7e7 - Show all commits

View File

@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.banutama.utamacraft.util.ModEnergyStorage;
import net.banutama.utamacraft.util.WorldScan.Side;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -20,7 +21,16 @@ import net.minecraftforge.common.util.LazyOptional;
public class AwarenessBlockEntity extends BlockEntity {
private static final int ENERGY_REQUIRED = 32;
private final ModEnergyStorage energy = new ModEnergyStorage(60000, 256) {
public static int getCost(int radius, Side side) {
int blocks = (int) Math.pow(radius * 2, 3);
if (side != Side.All) {
blocks >>= 1;
}
return blocks * ENERGY_REQUIRED;
}
private final ModEnergyStorage energy = new ModEnergyStorage(60000, 256, 256000) {
@Override
public void onEnergyChanged() {
setChanged();
@ -58,7 +68,7 @@ public class AwarenessBlockEntity extends BlockEntity {
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
energy.deserializeNBT(nbt.getCompound("energy"));
energy.deserializeNBT(nbt.get("energy"));
}
@Override
@ -81,14 +91,4 @@ public class AwarenessBlockEntity extends BlockEntity {
this.level.sendBlockUpdated(this.worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
}
}
public boolean deductEnergyUse(int radius) {
int cost = radius * ENERGY_REQUIRED;
if (energy.getMaxEnergyStored() >= cost) {
energy.extractEnergy(cost, false);
return true;
}
return false;
}
}

View File

@ -14,6 +14,7 @@ import dan200.computercraft.api.lua.MethodResult;
import net.banutama.utamacraft.block.entity.AwarenessBlockEntity;
import net.banutama.utamacraft.util.LuaConverter;
import net.banutama.utamacraft.util.WorldScan;
import net.banutama.utamacraft.util.WorldScan.Side;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
@ -21,6 +22,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.registries.ForgeRegistries;
@ -35,6 +37,43 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
this(new BlockEntityPeripheralOwner(blockEntity));
}
private AwarenessBlockEntity getBlock() {
if (!(owner instanceof BlockEntityPeripheralOwner blockOwner)) {
return null;
}
BlockEntity blockEntity = blockOwner.getBlockEntity();
if (!(blockEntity instanceof AwarenessBlockEntity block)) {
return null;
}
return block;
}
@LuaFunction(mainThread = true)
public final int getEnergy() {
return getBlock().getCapability(ForgeCapabilities.ENERGY).map(IEnergyStorage::getEnergyStored).orElse(0);
}
@LuaFunction(mainThread = true)
public final int getEnergyCapacity() {
return getBlock().getCapability(ForgeCapabilities.ENERGY).map(IEnergyStorage::getMaxEnergyStored).orElse(0);
}
@LuaFunction(mainThread = true)
public final @NotNull MethodResult getCost(@NotNull IArguments arguments) throws LuaException {
int radius = arguments.getInt(0);
if (radius < 1) {
return MethodResult.of(null, "Radius must be greater than zero");
}
String sideString = arguments.optString(1, "all");
Side side = parseSide(sideString);
int cost = AwarenessBlockEntity.getCost(radius, side);
return MethodResult.of(cost);
}
@LuaFunction(mainThread = true)
public final @NotNull MethodResult scan(@NotNull IArguments arguments) throws LuaException {
int radius = arguments.getInt(0);
@ -42,6 +81,9 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
return MethodResult.of(null, "Radius must be greater than zero");
}
String sideString = arguments.optString(1, "all");
Side side = parseSide(sideString);
if (!(owner instanceof BlockEntityPeripheralOwner blockOwner)) {
return MethodResult.of(null, "Owner of this AwarenessBlockPeripheral is not a BlockEntityPeripheralOwner");
}
@ -52,6 +94,18 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
"Owner of this AwarenessBlockEntity has a BlockEntityProviderOwner with a BlockEntity that is not an AwarenessBlockEntity");
}
IEnergyStorage energy = block.getCapability(ForgeCapabilities.ENERGY).orElse(null);
if (energy == null) {
return MethodResult.of(null, "BlockEntity does not have an IEnergyStorage capability");
}
int energyCost = AwarenessBlockEntity.getCost(radius, side);
int energyUsed = energy.extractEnergy(energyCost, false);
if (energyUsed != energyCost) {
return MethodResult.of(null, String.format("Not enough energy available: %d/%d", energyUsed, energyCost));
}
Level level = blockEntity.getLevel();
BlockPos origin = blockEntity.getBlockPos();
@ -66,15 +120,44 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
}
List<Map<String, ?>> blocks = new ArrayList<>();
WorldScan.scanBlocks(level, origin, radius, (state, pos) -> {
WorldScan.scanBlocks(level, origin, radius, side, (state, pos) -> {
blocks.add(describeBlock(level, origin, state, pos));
});
{
Map<String, Object> energyMap = new HashMap<>();
energyMap.put("used", energyUsed);
energyMap.put("cost", energyCost);
result.put("energy", energyMap);
}
result.put("blocks", blocks);
result.put("side", sideString);
return MethodResult.of(result);
}
private static Side parseSide(String sideString) throws LuaException {
switch (sideString) {
case "all":
return Side.All;
case "up":
return Side.Up;
case "down":
return Side.Down;
case "north":
return Side.North;
case "east":
return Side.East;
case "south":
return Side.South;
case "west":
return Side.West;
default:
throw new LuaException("Invalid side");
}
}
private static HashMap<String, Object> describeBlock(Level level, BlockPos origin, BlockState state, BlockPos pos) {
HashMap<String, Object> blockInfo = new HashMap<>(5);

View File

@ -7,6 +7,10 @@ public abstract class ModEnergyStorage extends EnergyStorage {
super(capacity, maxTransfer);
}
public ModEnergyStorage(int capacity, int maxReceive, int maxExtract) {
super(capacity, maxReceive, maxExtract);
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
int extracted = super.extractEnergy(maxExtract, simulate);

View File

@ -2,20 +2,67 @@ package net.banutama.utamacraft.util;
import java.util.function.BiConsumer;
import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
public class WorldScan {
public static void scanBlocks(Level level, BlockPos origin, int r,
BiConsumer<BlockState, BlockPos> consumer) {
public enum Side {
All, Up, Down, North, East, South, West
}
// Generate a bounding box for the given origin, radius and block side.
private static BoundingBox getScanBounds(BlockPos origin, int r, Side side) {
int ox = origin.getX();
int oy = origin.getY();
int oz = origin.getZ();
for (int x = ox - r; x <= ox + r; ++x) {
for (int y = oy - r; y <= oy + r; ++y) {
for (int z = oz - r; z <= oz + r; ++z) {
int x1 = ox - r;
int y1 = oy - r;
int z1 = oz - r;
int x2 = ox + r;
int y2 = oy + r;
int z2 = oz + r;
switch (side) {
case Up:
y1 = oy;
break;
case Down:
y2 = oy;
break;
case North:
z1 = oz;
break;
case East:
x2 = ox;
break;
case South:
z2 = oz;
break;
case West:
x1 = ox;
break;
default:
break;
}
return new BoundingBox(x1, y1, z1, x2, y2, z2);
}
public static void scanBlocks(Level level, BlockPos origin, int r, Side side,
BiConsumer<BlockState, BlockPos> consumer) {
BoundingBox bounds = getScanBounds(origin, r, side);
int total = 0;
for (int x = bounds.minX(); x < bounds.maxX(); ++x) {
for (int y = bounds.minY(); y < bounds.maxY(); ++y) {
for (int z = bounds.minZ(); z < bounds.maxZ(); ++z) {
total += 1;
BlockPos pos = new BlockPos(x, y, z);
BlockState state = level.getBlockState(pos);
@ -25,5 +72,7 @@ public class WorldScan {
}
}
}
LogUtils.getLogger().info("Scanned {} blocks", total);
}
}