Fixing your command
Your problem here is that you are mixing up target selector arguments with data tags, and then some minor mistakes.
Target selector arguments, such as team=Moderators
(lowercase!) are placed in square brackets ([]
) directly with the target selector, such as @a
or @p
. They come in the form key=value
, with a predefined set of valid keys.
Data tag matching on the other hand is looking directly at the NBT data of an entity, such as ActiveEffects
. They are placed within curly brackets ({}
) and come in the form of key:value
. Only a fairly small subset of commands are capable of using data tags at all.
Your command in this case should be
/testfor @a[team=Moderators] {ActiveEffects:[{Id:21b,Amplifier:20b}]}
Fixing your setup
However, your whole idea is rubbish, if I may be so blunt. It looks like you are testing if there are moderators with Health Boost 20, then invert the signal and re-apply health boost. The first problem is that no moderator gets health boost unless none of the moderators currently have health boost. Actually negating data tag matching requires assigning scoreboard values based on the data tag.
For most effects, reapplying the effect all the time works just fine, e.g. run
/effect @a[team=Moderators] <effect> 1 <amplifier> true
on a fast clock (setblock/fill clock!) works just fine, and is actually way less resource-intensive than a redstone lag-machine with torches, comparators and whatnot.
However, there is an issue with reapplying Health Boost since it will reset your current health to 10 hearts all the time. If you want to reapply the effect only when needed, using /testfor
, comparators and redstone is still not a good idea. Instead, you should translate the data tag into a scoreboard value which can be used in a target selector. To do that, start by creating a scoreboard objective:
/scoreboard objectives add hasEffect dummy
Create a fill/setblock clock and put the following commands in order:
/scoreboard players set @a[team=Moderators] hasEffect 0
/scoreboard players set @a[team=Moderators] hasEffect 1 {ActiveEffects:[{Id:21b,Amplifier:20b}]}
/effect @a[team=Moderators,score_hasEffects=0] minecraft:health_boost 9999 20 true
An operation of 1 is multiplying against your current base, which is 0. 100% of 0 is still 0. You'll want to use an operation of 0 instead, which is addition (and a generic.knockbackResistance
of 1 is 100% chance to resist):
/replaceitem entity @p slot.inventory.0 minecraft:stone 1 0 {display:{Name:"Anti-Knockback",Lore:["Just so you arent affected by knockback"]},AttributeModifiers:[{AttributeName:"generic.knockbackResistance",Name:"generic.knockbackResistance",Amount:1,Operation:0,UUIDMost:82829,UUIDLeast:167220}]}
Best Answer
Running score method: Primitive, simple, but not as good as others
Details
The simplest solution is not to use an actual random generator at all, because it's not really needed. The randomness can come from a user input instead.
What I mean by that is that you can have a rapidly changing scoreboard objective, and evaluate the score at the moment a button is pressed.
First set up your randomness objective using
There used to be a
stat.playOneMinute
which would automatically increase it by 1 every single game tick without another command needed, and it will not be the same for every player (if that is not desired, resetting it for everyone works). However, because updates have removed this statistic, we would need to implement our own commands to increase it by one tick.Now create a fill/setblock clock and have it run
and you're done. To use your random numbers, make one command block for every single outcome and include
[score_RNG=X,score_RNG_min=X]
with your target selector arguments, whereX
is the score to use, running from 0 to 8(!). Trigger all of these at the same time. For exampleIf your command does not use a target selector argument, you can (ab)use
execute
for that, e.g.Nowadays in 1.13+, it is advised not to use this as there are much better alternatives and it requires a running function. This is however the most easy way to generate random numbers.