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.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=MIT License
|
mod_license=MIT License
|
||||||
# The mod version. See https://semver.org/
|
# 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.
|
# 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.
|
# This should match the base package used for the mod sources.
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
@ -1,11 +1,94 @@
|
|||||||
package net.banutama.utamacraft.block.entity;
|
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.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.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
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 {
|
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) {
|
public AwarenessBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(ModBlockEntities.AWARENESS_BLOCK.get(), pos, 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("progress", progress);
|
||||||
nbt.putInt("ticks", ticks);
|
nbt.putInt("ticks", ticks);
|
||||||
nbt.putBoolean("active", active);
|
nbt.putBoolean("active", active);
|
||||||
super.saveAdditional(nbt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
"homepage": "https://git.blakerain.com/bans-minecraft/utamacraft",
|
||||||
"1.19.2": {
|
"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.4-1.19": "Add some fixes and new textures",
|
||||||
"0.2.3-1.19": "Add CC peripheral for Insolator",
|
"0.2.3-1.19": "Add CC peripheral for Insolator",
|
||||||
"0.2.2-1.19": "Fix bugs with Insolator",
|
"0.2.2-1.19": "Fix bugs with Insolator",
|
||||||
@ -11,7 +13,7 @@
|
|||||||
"0.0.1-1.19": "Initial release"
|
"0.0.1-1.19": "Initial release"
|
||||||
},
|
},
|
||||||
"promos": {
|
"promos": {
|
||||||
"1.19.2-latest": "0.2.4-1.19",
|
"1.19.2-latest": "0.2.6-1.19",
|
||||||
"1.19.2-recommended": "0.2.4-1.19"
|
"1.19.2-recommended": "0.2.6-1.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user