Arqade Asked by IceMetalPunk on January 3, 2021
I’m trying to make a goalpost system for a custom map I’m designing. The idea is that a goalpost–consisting of a tall stack of iron bars–would have variable height, and at each block up and down the post there would be an armor stand. These armor stands would have a GoalScore score value which increases from bottom to top, so that when the player comes into contact with one of them, they can have their score increased more the higher they hit it (Mario style). Since this requires a lot of armor stands, and there will be multiple goalposts in the map of varying height, I’m trying to make their generation easy on myself by having any Goal armor stand with air under it automatically generate a goalpost.
Here’s the commands I’m using, each in a chain block (except the first, which is in a repeat block so the whole thing runs 20 times per second):
/scoreboard players add @e[type=ArmorStand,name=Goal] GoalScore 0
/scoreboard players set @e[type=ArmorStand,name=Goal] hasAirUnder 0
/execute @e[type=ArmorStand,name=Goal] ~ ~ ~ detect ~ ~-1 ~ minecraft:air -1 /scoreboard players set @e[type=ArmorStand,name=Goal,c=1] hasAirUnder 1
/execute @e[type=ArmorStand,name=Goal,score_hasAirUnder_min=1] ~ ~ ~ /summon ArmorStand ~ ~-1 ~ {CustomName:"Goal", NoGravity:1b}
/execute @e[type=ArmorStand,name=Goal,score_hasAirUnder_min=1] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,name=Goal,dy=-1,dx=0,dz=0] GoalScore = @e[type=ArmorStand,name=Goal,c=1] GoalScore
/execute @e[type=ArmorStand,name=Goal,score_hasAirUnder_min=1] ~ ~2 ~ /scoreboard players add @e[type=ArmorStand,name=Goal,dy=255,dx=0,dz=0] GoalScore 1
/execute @e[type=ArmorStand,name=Goal,score_hasAirUnder_min=1] ~ ~ ~ /setblock ~ ~-1 ~ minecraft:iron_bars 0
The idea is that any goal armor stands with air under them will summon a new goal armor stand below them, copy their current GoalScore to the new stand, then add 1 to every GoalScore for armor stands above them. Then it sets the block below to iron bars to stop it from triggering again the next tick.
While the idea seems sound, the execution isn’t quite working. Depending on the height of the initial armor stand, either a few of the bottom ones have their scores set to 0 and it doesn’t start counting up until a few blocks above (only the bottom one should have a score of 0); or, sometimes, it doesn’t count all the way to 0 and somehow stops at 2 or 3 or something. It’s as though the dy=255
I’m using in the GoalScore-increasing command isn’t working properly; rather than selecting all armor stands above (and including) the current one for incrementing, it seems sometimes it selects none, or selects armor stands below it as well.
(If I change the execution coordinates of that to ~ ~ ~
, every goal armor stand gets the same final, maximum value; if I change it to ~ ~1 ~
, the top value is correct, while every other value is duplicated as top_value - 1
. Using ~ ~2 ~ is the only way I get it to count down without skipping or duplicates, but then it has the problems I mentioned above.)
Am I doing something wrong? How can I make this work as expected?
What I would do is summon another ArmorStand under and increment all existing ones within certain range, maybe just those that have same X and Y coordinates. That way it would not interfere with other existing goalposts.
Alternatively, once you reach ground, lock all existing goalposts (by using another scoreboard objective). When you create new goalpost, you could again summon ArmorStands under and increment the score for those that are not locked yet.
Answered by TakeruDavis on January 3, 2021
If I were you, I'd do it this way (which works for me, i just tested it):
instead of using the operation, make the armor_stands add a score to each above them like so (updated to 1.11):
/scoreboard players tag @e[type=armor_stand,name=Goal] remove hasAirUnder
/scoreboard players set @e[type=armor_stand,name=Goal] GoalScore 0
/execute @e[type=armor_stand,name=Goal] ~ ~ ~ detect ~ ~-1 ~ minecraft:air * /scoreboard players tag @e[type=armor_stand,c=1] add hasAirUnder
/execute @e[type=armor_stand,name=Goal,tag=hasAirUnder] ~ ~ ~ /summon armor_stand ~ ~-1 ~ {CustomName:"Goal",NoGravity:1,Marker:1}
/execute @e[type=armor_stand,name=Goal,tag=hasAirUnder] ~ ~ ~ /setblock ~ ~-1 ~ iron_bars
/execute @e[type=armor_stand,name=Goal] ~ ~1 ~ /scoreboard players add @e[type=armor_stand,name=Goal,dx=0,dy=255,dz=0] GoalScore 1
for some weird reason that i don't quite get rn, you have to execute the last command 3 blocks above the armorstands, or else it will count up too high and give the top three armorstands the same score... no idea where this comes from tbh
but whatever, this way it works. :D
EDIT: As SirBenet informed me, it's because the armorstands hitbox overlaps with the dy=255 region. To counteract this, you have to change the armorstands to markers (or use areaeffectclouds in the first place). this is likely what broke your system as well.
so all you need to do to make this work the way you want it is to execute one block above each stand (since you want the count to start with 0 and not 1). I edited my post so you can just take the commands i wrote above.
Answered by Plagiatus on January 3, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP