2

I have a objective called DIFF. When a player hits a button, I would like to give them items based on their DIFF count multiplied by two. For instance: if DIFF is 1 then give them 2 items, if DIFF is 2 then give them 4 items, etc.

My current command (without multiplication):

/give @p minecraft:emerald {"score":{"name":"@p","objective":"DIFF"}}

But it says "score" is not a valid number. How can I use the player's score to determine the number of items when using /give?

4

Yeah, commands don't work like that. They're highly structured, and don't allow you to replace expected integers with expressions. You're going to have to do this the hard way. You'll also want to be using 1.9 for command block simplicity, although this solution will also work in 1.8 with well structured 20Hz clocks.

First, we need to set up another scoreboard objective that represents the number of items to give; let's call it NumItems:

/scoreboard objectives add NumItems dummy

We also need an intermediate scoreboard objective to avoid race conditions in the latter stages. This objective is what is going to multiply the DIFF score, so we'll call it Multiplier:

/scoreboard objectives add Multiplier dummy

Now, when a player hits the button, they need their NumItems score set to two times their DIFF score. We do that with the following commands:

/scoreboard players set @p Multiplier 2
/scoreboard players operation @p Multiplier *= @p DIFF
/scoreboard players operation @p NumItems = @p Multiplier

Great, now we have a number of items to give, we just need to give them... one at a time. Well, we can be a little more efficient than that, but we can't just give an arbitrary number of items. We'll break it down into giving 1 item, 10 items, and a stack of 64 items. Create a chain of command blocks off a repeating command block (or use a 20Hz clock) for these commands, edited to meet your needed specifics:

/give @a[score_NumItems_min=64] <item> 64 [...]
/scoreboard players remove @a[score_NumItems_min=64] NumItems 64
/give @a[score_NumItems_min=10] <item> 10 [...]
/scoreboard players remove @a[score_NumItems_min=10] NumItems 10
/give @a[score_NumItems_min=1] <item> 1 [...]
/scoreboard players remove @a[score_NumItems_min=1] NumItems 1

This is only one possible distribution of give values, and can easily be improved by choosing a geometric sequence like 2n (1, 2, 4, 8...), which should complete all give operations for item counts up to 128 in 1 or 2 ticks.


It should be apparent why we need the Multiplier objective, but in case it's not, it's so that we don't start giving items before DIFF has been doubled. As such, we should only write to the NumItems once when the button is pressed. Even though the likelihood of encountering a race condition error is low without using the Multiplier objective, it's best to avoid the problem entirely.

  • well you could leave out multiplier by just setting NumItems equal to DIFF and giving twice as many items per /give command (so give 2 items but remove 1 score, etc.), but the way you have it is much better programming style, and as a bonus you can change the multiplier by editing just one place. – Nick Feb 15 '16 at 23:21
  • That's the primary reason for doing it this way. It also makes it much easier to set up the repeating commands. As an additional bonus, the multiplier can easily be changed on the fly, for instance as a level up mechanic. That of course would require another objective as well (or to store it in a non-player scoreboard value). – MBraedley Feb 16 '16 at 2:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.