Updates to the awareness block #55
@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import net.banutama.utamacraft.util.ModEnergyStorage;
|
import net.banutama.utamacraft.util.ModEnergyStorage;
|
||||||
|
import net.banutama.utamacraft.util.WorldScan.Side;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@ -20,7 +21,16 @@ import net.minecraftforge.common.util.LazyOptional;
|
|||||||
public class AwarenessBlockEntity extends BlockEntity {
|
public class AwarenessBlockEntity extends BlockEntity {
|
||||||
private static final int ENERGY_REQUIRED = 32;
|
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
|
@Override
|
||||||
public void onEnergyChanged() {
|
public void onEnergyChanged() {
|
||||||
setChanged();
|
setChanged();
|
||||||
@ -58,7 +68,7 @@ public class AwarenessBlockEntity extends BlockEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void load(@NotNull CompoundTag nbt) {
|
public void load(@NotNull CompoundTag nbt) {
|
||||||
super.load(nbt);
|
super.load(nbt);
|
||||||
energy.deserializeNBT(nbt.getCompound("energy"));
|
energy.deserializeNBT(nbt.get("energy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,14 +91,4 @@ public class AwarenessBlockEntity extends BlockEntity {
|
|||||||
this.level.sendBlockUpdated(this.worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
|
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.block.entity.AwarenessBlockEntity;
|
||||||
import net.banutama.utamacraft.util.LuaConverter;
|
import net.banutama.utamacraft.util.LuaConverter;
|
||||||
import net.banutama.utamacraft.util.WorldScan;
|
import net.banutama.utamacraft.util.WorldScan;
|
||||||
|
import net.banutama.utamacraft.util.WorldScan.Side;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.Level;
|
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.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||||
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
@ -35,6 +37,43 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
|
|||||||
this(new BlockEntityPeripheralOwner(blockEntity));
|
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)
|
@LuaFunction(mainThread = true)
|
||||||
public final @NotNull MethodResult scan(@NotNull IArguments arguments) throws LuaException {
|
public final @NotNull MethodResult scan(@NotNull IArguments arguments) throws LuaException {
|
||||||
int radius = arguments.getInt(0);
|
int radius = arguments.getInt(0);
|
||||||
@ -42,6 +81,9 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
|
|||||||
return MethodResult.of(null, "Radius must be greater than zero");
|
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)) {
|
if (!(owner instanceof BlockEntityPeripheralOwner blockOwner)) {
|
||||||
return MethodResult.of(null, "Owner of this AwarenessBlockPeripheral is not a BlockEntityPeripheralOwner");
|
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");
|
"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();
|
Level level = blockEntity.getLevel();
|
||||||
BlockPos origin = blockEntity.getBlockPos();
|
BlockPos origin = blockEntity.getBlockPos();
|
||||||
|
|
||||||
@ -66,15 +120,44 @@ public class AwarenessBlockPeripheral extends BasePeripheral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Map<String, ?>> blocks = new ArrayList<>();
|
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));
|
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("blocks", blocks);
|
||||||
|
result.put("side", sideString);
|
||||||
|
|
||||||
return MethodResult.of(result);
|
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) {
|
private static HashMap<String, Object> describeBlock(Level level, BlockPos origin, BlockState state, BlockPos pos) {
|
||||||
HashMap<String, Object> blockInfo = new HashMap<>(5);
|
HashMap<String, Object> blockInfo = new HashMap<>(5);
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ public abstract class ModEnergyStorage extends EnergyStorage {
|
|||||||
super(capacity, maxTransfer);
|
super(capacity, maxTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModEnergyStorage(int capacity, int maxReceive, int maxExtract) {
|
||||||
|
super(capacity, maxReceive, maxExtract);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int extractEnergy(int maxExtract, boolean simulate) {
|
public int extractEnergy(int maxExtract, boolean simulate) {
|
||||||
int extracted = super.extractEnergy(maxExtract, simulate);
|
int extracted = super.extractEnergy(maxExtract, simulate);
|
||||||
|
@ -2,20 +2,67 @@ package net.banutama.utamacraft.util;
|
|||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||||
|
|
||||||
public class WorldScan {
|
public class WorldScan {
|
||||||
public static void scanBlocks(Level level, BlockPos origin, int r,
|
public enum Side {
|
||||||
BiConsumer<BlockState, BlockPos> consumer) {
|
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 ox = origin.getX();
|
||||||
int oy = origin.getY();
|
int oy = origin.getY();
|
||||||
int oz = origin.getZ();
|
int oz = origin.getZ();
|
||||||
|
|
||||||
for (int x = ox - r; x <= ox + r; ++x) {
|
int x1 = ox - r;
|
||||||
for (int y = oy - r; y <= oy + r; ++y) {
|
int y1 = oy - r;
|
||||||
for (int z = oz - r; z <= oz + r; ++z) {
|
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);
|
BlockPos pos = new BlockPos(x, y, z);
|
||||||
BlockState state = level.getBlockState(pos);
|
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