Solved Loop air inside of a room

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

ShaneBee

Supporter +
Addon Developer
Sep 7, 2017
2,248
241
73
Vancouver, Canada
Category: n/a

Suggested name: n/a (Will be part of another skript)

What I want:
I want to be able to run a command, to loop the air blocks inside of a room and return the number of blocks.
For Example, I'm standing in a 10x3x10 room, i run said command and it'll return to me "300 blocks of air"


Ideas for commands:
/room

Ideas for permissions:
n/a

When I'd like it by: Soon would be nice.

Extra Notes:
I was told by someone before to look at the functions from a competition where they filled the room with blocks. I tried testing with that first but the functions listed on the page ran errors.
COMPETITION


I do not require anything extravagant, as I can edit it later when I work it into a much larger Skript. I just need the basics right now to return to me the number of air blocks in the room.

Thanks in advance.
 
Hi! I needed to know is like /room [<radius>] enough, or if a wall comes the loop won't go further

Thanks,
Peivi
[doublepost=1522086857,1522086085][/doublepost]I made this skript in few seconds. It may be broken because im super tired and im too lazy to test it. Im sorry D:

Hope it helps!

code_language.skript:
options:
  perm: room.test
  permmessage: &cYou don't have enough permissions.

command /room [<player>] [<number>]:
  usage: &c/room <radius> - checks how many air blocks is there around the argument player
  permission: {@perm}
  permission message: {@permmessage}
  trigger:
    if arg-1 is set:
      if arg-2 is set:
        set {blocks.around.%player%} to 0
        set {room.%player%} to arg-2
        message "&cProcessing..."
        loop all blocks in radius {room.%player%} around the player-argument:
          if loop-block is air:
            add 1 to {blocks.around.%player%}
          #Just to make sure all blocks are looped :P
          wait 2 seconds
          message "&cThere is &e%{blocks.around.%player%}% &cair blocks around &e%arg-1%"
          delete {room.%player%}
          delete {blocks.around.%player%}
 
If im right you can maybe do that with around the player. if it loops like:

Player: o

Air Block: [1] (like first block to be looped = 1)

Other block: ()

() [5] [4] [3] [2] [1] o [1] [2] [3] [4] [5] ()

Its hard to explain and im tired, as always

Hope it helps even a bit!
 
When you loop blocks radius around a player, it loops outside the walls off the room. For instance if you loop in a radius of 10 around the player, it will loop all blocks 10 out from you, including the air outside the room.
 
I know. But do skript loop first closest blocks of the player? If answer is yes. I maybe can solve this.
 
code_language.skript:
function countAir(loc: location, p: player):
    loop blocks in radius 1 around {_loc}:
        set {_alreadyCounted} to false
        loop {air::%{_p}%::*}:
            if loop-value-1 is loop-value-2:
                set {_alreadyCounted} to true
        if {_alreadyCounted} is false:
            if loop-block is air:
                add loop-block to {air::%{_p}%::*}
                wait 1 tick
                countAir(loop-block's location, "%{_p}%" parsed as player)

command /room:
    trigger:
        clear {air::%player%::*}
        send "&aCalculating..."
        countAir(player's location, player)
        wait 3 seconds
        send "&6Air blocks: &e%size of {air::%player%::*}%"
the wait 3 seconds in the second last line is needed to give the function time to collect the blocks since its not instant. i tested with a room that was about 1000 air blocks and 3 seconds was enough time but if your rooms are really big then youll need to increase the wait time. also if you do the command outside a room your server will break. To prevent that you could add a check in the function for if size of {air::%player%::*} is greater than idk 50000 or something which at that point you could reasonably assume the player is outside and stop the process

there might be a better way to do this but this was the best i could come up with
 
code_language.skript:
function countAir(loc: location, p: player):
    loop blocks in radius 1 around {_loc}:
        set {_alreadyCounted} to false
        loop {air::%{_p}%::*}:
            if loop-value-1 is loop-value-2:
                set {_alreadyCounted} to true
        if {_alreadyCounted} is false:
            if loop-block is air:
                add loop-block to {air::%{_p}%::*}
                wait 1 tick
                countAir(loop-block's location, "%{_p}%" parsed as player)

command /room:
    trigger:
        clear {air::%player%::*}
        send "&aCalculating..."
        countAir(player's location, player)
        wait 3 seconds
        send "&6Air blocks: &e%size of {air::%player%::*}%"
the wait 3 seconds in the second last line is needed to give the function time to collect the blocks since its not instant. i tested with a room that was about 1000 air blocks and 3 seconds was enough time but if your rooms are really big then youll need to increase the wait time. also if you do the command outside a room your server will break. To prevent that you could add a check in the function for if size of {air::%player%::*} is greater than idk 50000 or something which at that point you could reasonably assume the player is outside and stop the process

there might be a better way to do this but this was the best i could come up with

Thanks a bunch donut. I ended up figuring something out and it works but it doesn’t look so pretty on skript. But i’ll definitely give this a try.