package me.km.snuviscript.commands; import com.mojang.brigadier.StringReader; import me.hammerle.snuviscript.code.ScriptManager; import me.hammerle.snuviscript.code.SnuviUtils; import me.km.inventory.InventoryUtils; import me.km.utils.Location; import me.km.utils.Mapper; import net.minecraft.block.*; import net.minecraft.command.arguments.BlockStateParser; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.state.Property; import net.minecraft.state.properties.ChestType; import net.minecraft.tags.BlockTags; import net.minecraft.tags.Tag; import net.minecraft.tileentity.*; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.IWorld; import net.minecraft.world.World; public class BlockCommands { private static class Offset { private final int x; private final int y; private final int z; public Offset(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } private static final Offset[] OFFSETS = new Offset[]{ //new Offset(-1, -1, -1), new Offset(0, -1, -1), //new Offset(1, -1, -1), new Offset(-1, 0, -1), new Offset(0, 0, -1), new Offset(1, 0, -1), //new Offset(-1, 1, -1), new Offset(0, 1, -1), //new Offset(1, 1, -1), new Offset(-1, -1, 0), new Offset(0, -1, 0), new Offset(1, -1, 0), new Offset(-1, 0, 0), new Offset(0, 0, 0), new Offset(1, 0, 0), new Offset(-1, 1, 0), new Offset(0, 1, 0), new Offset(1, 1, 0), //new Offset(-1, -1, 1), new Offset(0, -1, 1), //new Offset(1, -1, 1), new Offset(-1, 0, 1), new Offset(0, 0, 1), new Offset(1, 0, 1), //new Offset(-1, 1, 1), new Offset(0, 1, 1), //new Offset(1, 1, 1), }; public static void registerFunctions(ScriptManager sm) { sm.registerFunction("block.gettag", (sc, in) -> BlockTags.getCollection().get(new ResourceLocation(in[0].getString(sc)))); sm.registerFunction("block.hastag", (sc, in) -> ((Tag) in[0].get(sc)).contains((Block) in[1].get(sc))); sm.registerFunction("block.gettype", (sc, in) -> { Location l = (Location) in[0].get(sc); return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getRegistryName().toString(); }); sm.registerFunction("block.isair", (sc, in) -> { Location l = (Location) in[0].get(sc); return l.getWorld().isAirBlock(l.getBlockPos()); }); sm.registerFunction("block.countair", (sc, in) -> { Location l = (Location) in[0].get(sc); IWorld w = l.getWorld(); BlockPos oldPos = l.getBlockPos(); BlockPos.Mutable pos = new BlockPos.Mutable(oldPos.getX(), oldPos.getY(), oldPos.getZ()); int ox = pos.getX(); int oy = pos.getY(); int oz = pos.getZ(); double counter = 0; for(Offset off : OFFSETS) { pos.setPos(ox + off.x, oy + off.y, oz + off.z); if(w.isAirBlock(pos)) { counter++; } } return counter; }); sm.registerFunction("block.get", (sc, in) -> { Location l = (Location) in[0].get(sc); return l.getWorld().getBlockState(l.getBlockPos()).getBlock(); }); sm.registerFunction("block.getproperty", (sc, in) -> Mapper.getProperty(in[0].getString(sc))); sm.registerFunction("block.getstate", (sc, in) -> { Location l = (Location) in[0].get(sc); Property prop = (Property) in[1].get(sc); BlockState state = l.getWorld().getBlockState(l.getBlockPos()); if(state.hasProperty(prop)) { Object o = l.getWorld().getBlockState(l.getBlockPos()).get(prop); if(o instanceof Number) { return ((Number) o).doubleValue(); } else if(o instanceof Boolean) { return o; } return o.toString(); } return null; }); sm.registerConsumer("block.clone", (sc, in) -> { Location l0 = (Location) in[0].get(sc); Location l1 = (Location) in[1].get(sc); IWorld w0 = l0.getWorld(); BlockPos pos0 = l0.getBlockPos(); BlockState state = w0.getBlockState(pos0); TileEntity tileEnt0 = w0.getTileEntity(pos0); IWorld w1 = l1.getWorld(); BlockPos pos1 = l1.getBlockPos(); w1.setBlockState(pos1, state, 2); TileEntity tileEnt1 = w1.getTileEntity(pos1); if(tileEnt0 != null && tileEnt1 != null) { CompoundNBT nbt = tileEnt0.write(new CompoundNBT()); nbt.putInt("x", pos1.getX()); nbt.putInt("y", pos1.getY()); nbt.putInt("z", pos1.getZ()); tileEnt1.read(w1.getBlockState(pos1), nbt); tileEnt1.markDirty(); } }); sm.registerConsumer("block.set", (sc, in) -> { Location l = (Location) in[0].get(sc); BlockStateParser parser = new BlockStateParser(new StringReader(in[1].getString(sc)), true); BlockState state = parser.parse(true).getState(); int flag = 2; if(in.length >= 3 && in[2].getBoolean(sc)) { flag |= 16; } l.getWorld().setBlockState(l.getBlockPos(), state, flag); }); sm.registerFunction("block.newstate", (sc, in) -> { BlockStateParser parser = new BlockStateParser(new StringReader(in[0].getString(sc)), true); return parser.parse(true).getState(); }); sm.registerConsumer("block.setstate", (sc, in) -> { Location l = (Location) in[0].get(sc); int flag = 2; if(in.length >= 3 && in[2].getBoolean(sc)) { flag |= 16; } l.getWorld().setBlockState(l.getBlockPos(), (BlockState) in[1].get(sc), flag); }); sm.registerFunction("block.setsign", (sc, in) -> { Location l = (Location) in[0].get(sc); TileEntity te = l.getWorld().getTileEntity(l.getBlockPos()); if(te == null || !(te instanceof SignTileEntity)) { return false; } SignTileEntity sign = (SignTileEntity) te; sign.setText(in[1].getInt(sc), new StringTextComponent(SnuviUtils.connect(sc, in, 2))); SUpdateTileEntityPacket packet = sign.getUpdatePacket(); l.getWorld().getPlayers().forEach(p -> ((ServerPlayerEntity) p).connection.sendPacket(packet)); return true; }); sm.registerFunction("block.getsign", (sc, in) -> { Location l = (Location) in[0].get(sc); TileEntity te = l.getWorld().getTileEntity(l.getBlockPos()); if(te == null || !(te instanceof SignTileEntity)) { return null; } return ((SignTileEntity) te).getText(in[1].getInt(sc)).getString(); }); sm.registerConsumer("block.setdoorstatus", (sc, in) -> { Location l = (Location) in[0].get(sc); BlockPos pos = l.getBlockPos(); BlockState state = l.getWorld().getBlockState(pos); ((DoorBlock) state.getBlock()).openDoor((World) l.getWorld(), state, pos, in[1].getBoolean(sc)); }); sm.registerFunction("block.getdoorstatus", (sc, in) -> { Location l = (Location) in[0].get(sc); return l.getBlockState().get(DoorBlock.OPEN); }); sm.registerFunction("block.isdoor", (sc, in) -> { Location l = (Location) in[0].get(sc); return l.getWorld().getBlockState(l.getBlockPos()).getBlock() instanceof DoorBlock; }); sm.registerFunction("block.issolid", (sc, in) -> { return CommandUtils.getBlockState((Location) in[0].get(sc)).isSolid(); }); sm.registerFunction("block.tostack", (sc, in) -> { Location l = (Location) in[0].get(sc); return new ItemStack(l.getBlockState().getBlock().asItem()); }); sm.registerFunction("block.getitemamount", (sc, in) -> { Location l = (Location) in[0].get(sc); TileEntity te = l.getWorld().getTileEntity(l.getBlockPos()); if(te == null || !(te instanceof ChestTileEntity)) { return 0.0d; } return (double) InventoryUtils.searchInventoryFor((ChestTileEntity) te, (ItemStack) in[2].get(sc), in[1].getBoolean(sc)); }); sm.registerFunction("block.getsecchest", (sc, in) -> { Location l = (Location) in[0].get(sc); BlockPos pos = l.getBlockPos(); BlockState state = l.getWorld().getBlockState(pos); ChestType chesttype = state.get(ChestBlock.TYPE); if(chesttype == ChestType.SINGLE) { return null; } Direction dir = ChestBlock.getDirectionToAttached(state); return l.copyAdd(dir.getXOffset(), dir.getYOffset(), dir.getZOffset()); }); sm.registerFunction("block.additem", (sc, in) -> { Location l = (Location) in[0].get(sc); ItemStack stack = ((ItemStack) in[1].get(sc)); TileEntity te = l.getWorld().getTileEntity(l.getBlockPos()); if(te == null || !(te instanceof ChestTileEntity)) { return stack; } stack.setCount(InventoryUtils.addToInventory((ChestTileEntity) te, stack)); return stack; }); sm.registerFunction("block.subitem", (sc, in) -> { Location l = (Location) in[0].get(sc); ItemStack stack = ((ItemStack) in[1].get(sc)); TileEntity te = l.getWorld().getTileEntity(l.getBlockPos()); if(te == null || !(te instanceof ChestTileEntity)) { return stack; } stack.setCount(InventoryUtils.removeFromInventory((ChestTileEntity) te, stack)); return stack; }); sm.registerConsumer("block.setspawnertype", (sc, in) -> { Location l = (Location) in[0].get(sc); MobSpawnerTileEntity spawner = (MobSpawnerTileEntity) l.getWorld().getTileEntity(l.getBlockPos()); spawner.getSpawnerBaseLogic().setEntityType(EntityType.byKey(in[1].getString(sc)).get()); }); sm.registerFunction("block.getinv", (sc, in) -> { Location l = (Location) in[0].get(sc); return (IInventory) l.getWorld().getTileEntity(l.getBlockPos()); }); } }