I was looking for a way to check if a player is exposed (no roof or anything) for a project and ended up thinking of one, but I failed to create it.
I found out that spreadplayer will tp the armorstand to the highest block on the xz cords and used Pos[1](y cord) with store to store the Y value.Then, i'd subtract the armorstand score to mine, so if it's +, then it's above, and bellow is -.Then, to prevente lag, it would take sometime to refresh and repeat the process.
But I found bug and can't find a way to fix it. The problem I stumbled upon was that if the armorstand is bellow,it would get a - score value and die as expected, but after 3 times of killing itself, it would emit a positive signal (even though the score displayed as always -) and trigger as if it were above me.
World download: World Download
A little messed up but here is the chart: Print
Since I'm looking foward to use it in Multiplayer, creating a unique armorstand to each player simultaneosly is pretty hard. I found out that spreadplayer will tp the armorstand to the highest block on the xz cords and used Pos[1](y cord) with store to store the Y value.Then, i'd subtract the armorstand score to mine, so if it's +, then it's above, and bellow is -.Then, to prevente lag, it would take sometime to refresh and repeat the process.
72 Answers
When you want to detect this on a multiplayer server, I would create a plugin, whichs checks, if it's raining (by getting the weather of the world of the player) and if the weather is actually affecting the biome at the players location (e.g. there is no rain in the desert). If this all is given and the block below the player is also the highest block at the players location, then the player is 'affected' of the rain.
2The simpliest solution:
/execute as [selector] at @s if blocks ~ ~1 ~ ~ 255 ~ x y z all run scoreboard players set @s [name] 1
/execute as [selector] at @s unless blocks ~ ~1 ~ ~ 255 ~ x y z all run scoreboard players set @s [name] 0Where [name] stands for the scoreboard name of your choice, [selector] is the player or entity you are looking to test for and x y z is a coordinate of the world where it should be all air(only the block of that coordinate and all above).
1 means he is exposed and 0 means he is in cover.
I had to do it again, and came back here since I found a better solution since it uses recursion, is cheap and doesn't require any pre empty space. This only works with datapacks
In short, what it does is:
- Set player's Y score to his Y pos
- Add player's Y score by 1
- Check if block above him is air (Using positioned). If so, Go back to step 2
Note here that using positioned will slowly move the referencial pos up, instead of using the player's initial pos.
Let us create the scoreboard:
/scoreboard objectives add y dummyIn a file, let us call it main.mcfunction, do:
## Reset tag
tag @s remove exposed
## Do the recursive function
# Save player's y pos into the score
execute store result score @s y run data get entity @s Pos[1]
execute as @s at @s run function <namespace:our_rec_function>
# Tag player if is exposed to sky
execute if score @s y_trace matches 255 run tag @s add exposedAnd our <our_rec_function.mcfunction> file will have:
scoreboard players add @s y 1
execute if score @s y matches ..254 positioned ~ ~1 ~ if block ~ ~ ~ air run function <namespace:our_rec_function>Really clever solution, and really compact. Love it!
Simply change the function <namespace:function> to the appropriate names based on your file structure.