Updates to the awareness block #55
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user