Updates to the awareness block #55
@ -56,7 +56,7 @@ mod_name=Utamacraft Mod
|
||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=MIT License
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.2.4-1.19
|
||||
mod_version=0.2.6-1.19
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
@ -1,11 +1,94 @@
|
||||
package net.banutama.utamacraft.block.entity;
|
||||
|
||||
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;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
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.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class AwarenessBlockEntity extends BlockEntity {
|
||||
private static final int ENERGY_REQUIRED = 4;
|
||||
|
||||
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();
|
||||
AwarenessBlockEntity.this.sendUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
private final LazyOptional<ModEnergyStorage> energyOptional = LazyOptional.of(() -> energy);
|
||||
|
||||
public AwarenessBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(ModBlockEntities.AWARENESS_BLOCK.get(), pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (cap == ForgeCapabilities.ENERGY) {
|
||||
return energyOptional.cast();
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
energyOptional.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(@NotNull CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("energy", energy.serializeNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
energy.deserializeNBT(nbt.get("energy"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompoundTag getUpdateTag() {
|
||||
CompoundTag nbt = super.getUpdateTag();
|
||||
saveAdditional(nbt);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Packet<ClientGamePacketListener> getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
private void sendUpdate() {
|
||||
setChanged();
|
||||
|
||||
if (this.level != null) {
|
||||
this.level.sendBlockUpdated(this.worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,6 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider {
|
||||
nbt.putInt("progress", progress);
|
||||
nbt.putInt("ticks", ticks);
|
||||
nbt.putBoolean("active", active);
|
||||
super.saveAdditional(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": ["iii", "tet", "tpt"],
|
||||
"key": {
|
||||
"i": {
|
||||
"item": "minecraft:iron_ingot"
|
||||
},
|
||||
"e": {
|
||||
"item": "minecraft:ender_eye"
|
||||
},
|
||||
"t": {
|
||||
"item": "utamacraft:tungsten_ingot"
|
||||
},
|
||||
"p": {
|
||||
"item": "utamacraft:pcb"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "utamacraft:awareness_block",
|
||||
"count": 1
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"homepage": "https://git.blakerain.com/bans-minecraft/utamacraft",
|
||||
"1.19.2": {
|
||||
"0.2.6-1.19": "Fix the excessive cost of the awareness block",
|
||||
"0.2.5-1.19": "Add the awareness block peripheral",
|
||||
"0.2.4-1.19": "Add some fixes and new textures",
|
||||
"0.2.3-1.19": "Add CC peripheral for Insolator",
|
||||
"0.2.2-1.19": "Fix bugs with Insolator",
|
||||
@ -11,7 +13,7 @@
|
||||
"0.0.1-1.19": "Initial release"
|
||||
},
|
||||
"promos": {
|
||||
"1.19.2-latest": "0.2.4-1.19",
|
||||
"1.19.2-recommended": "0.2.4-1.19"
|
||||
"1.19.2-latest": "0.2.6-1.19",
|
||||
"1.19.2-recommended": "0.2.6-1.19"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user