TransWikia.com

How do I change the color of a sheep to match a block of wool in a chest?

Arqade Asked by ShadowsHyper176 on November 28, 2020

I am trying to make a printer with sheep. I have a double chest for the printer input and sheep correspond to the slots in the chest. There are 54 sheep corresponding to the 54 slots. What command can I run to make the color of wool in a specific slot in a chest the same color as the corresponding sheep? And how can I copy it 54 times so I can do it for each slot/sheep?

One Answer

The problem this comes down to is: How do I loop through the elements of an NBT array? Luckily I already have an answer to that: Dynamically sized NBT array

The "tedious method" would in your case require 864 (54×16) commands, like this:

/execute if entity @e[type=sheep,limit=1,nbt={Color:0b},scores={slot=0}] run data modify block ~ ~ ~ Items[{Slot:0b}].id set value "white_wool"
/execute if entity @e[type=sheep,limit=1,nbt={Color:0b},scores={slot=0}] run data modify block ~ ~ ~ Items[{Slot:0b}].id set value "orange_wool"
…
/execute if entity @e[type=sheep,limit=1,nbt={Color:0b},scores={slot=1}] run data modify block ~ ~ ~ Items[{Slot:1b}].id set value "white_wool"
…

That's very tedious. It's probably slightly better for performance than what I'm about to suggest, but it's not well generalisable for other cases and it's not as clever. ;)

I'll assume here that all slots are filled, so index and slot number are identical. If that is not the case, you'll have to use something like the "search" method from my linked post. I'll also assume that all the sheep have their desired slot number saved in a scoreboard called "slot". You'll have to target them properly somehow, a scoreboard is a good idea for that.

First, copy the entire chest's Items array somewhere else:

/data modify storage fabian:sheep items set from block ~ ~-1 ~ Items

And initialise a scoreboard to 0:

/scoreboard objectives add slot dummy
/scoreboard players set $current slot 0

Now you need a loop, I would suggest a function with recursive calls for this. I'll call mine fabian:copy_sheep. Here is the complete function:

data modify storage fabian:sheep curr_item set from storage fabian:sheep items[0].id
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:white_wool"} run data merge entity @s {Color:0}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:orange_wool"} run data merge entity @s {Color:1}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:magenta_wool"} run data merge entity @s {Color:2}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:light_blue_wool"} run data merge entity @s {Color:3}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:yellow_wool"} run data merge entity @s {Color:4}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:lime_wool"} run data merge entity @s {Color:5}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:pink_wool"} run data merge entity @s {Color:6}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:gray_wool"} run data merge entity @s {Color:7}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:light_gray_wool"} run data merge entity @s {Color:8}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:cyan_wool"} run data merge entity @s {Color:9}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:purple_wool"} run data merge entity @s {Color:10}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:blue_wool"} run data merge entity @s {Color:11}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:brown_wool"} run data merge entity @s {Color:12}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:green_wool"} run data merge entity @s {Color:13}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:red_wool"} run data merge entity @s {Color:14}
execute as @e[type=sheep] if score @s slot = $current slot if data storage fabian:sheep {curr_item:"minecraft:black_wool"} run data merge entity @s {Color:15}
scoreboard players add $current slot 1
data remove storage fabian:sheep items[0]
execute if data storage fabian:sheep items[0] run function fabian:copy_sheep

Explanation:

Due to an oversight in the NBT path syntax items[0]{id:"minecraft:white_wool"} does not work. Therefore you need to first copy that tag somewhere else, in this case fabian:sheep curr_item.

Then you check every sheep for having the same value in the scoreboard "slot" as the fake player "$current". You can't use @e[scores={…}] here, because you need a dynamic number. When the sheep matches, it checks if the current item's ID is "white_wool" and if yes, sets its Color tag to 0 (which is white). Then this repeats for "orange_wool" and Color:1 and so on. This effectively means: Colour the sheep according to the current wool item.

The rest of the function increases the current slot counter, removes the first entry from the copied item list and continues the loop if there is an entry left. The reason why this is needed is that you can't dynamically access an array index based on a scoreboard value, so you need move the element forwards as many times as you want and then read from the fixed index 0.

Note that you need to do the setup again before repeating this process (except for the scoreboard creation).

I tried it here with a single chest, but it works the same with any inventory:

Answered by Fabian Röling on November 28, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP