Reapply Bad Omen if a player drinks milk until player triggers a raid?
Solution 1:
Caveats
- With the following methods, Death and Totem of Undying are both ways to get ride of both effects
Avoiding clearing Bad Omen
First, We create a scoreboard to track when a player drinks milk and track who has the effect:
/scoreboard objectives add milk minecraft.used:minecraft.milk_bucket
/scoreboard objectives add bad_omen dummy
To prevent a player from using milk to remove the effect, we will do 3 steps:
- Mark who has the effect, setting their
bad_omen
score to the level of the effect. We will need one block of command for each level, you can only get up to level V (5) in vanilla. - Apply the effect in anyone who has at least score 1 of
bad_omen
- Reset
milk
andbad_omen
(In case the bad omen effect ran out naturally, either because of time or raid)
So we translate those to:
Step 1:
/execute as @a[nbt={ActiveEffects:[{Id:31b,Amplifier:0b}]}] run scoreboard players set @s bad_omen 1
/execute as @a[nbt={ActiveEffects:[{Id:31b,Amplifier:1b}]}] run scoreboard players set @s bad_omen 2
/execute as @a[nbt={ActiveEffects:[{Id:31b,Amplifier:2b}]}] run scoreboard players set @s bad_omen 3
/execute as @a[nbt={ActiveEffects:[{Id:31b,Amplifier:3b}]}] run scoreboard players set @s bad_omen 4
/execute as @a[nbt={ActiveEffects:[{Id:31b,Amplifier:4b}]}] run scoreboard players set @s bad_omen 5
Step 2:
/execute as @a[scores={bad_omen=1,milk=1}] run effect give @s minecraft:bad_omen 999999 0
/execute as @a[scores={bad_omen=2,milk=1}] run effect give @s minecraft:bad_omen 999999 1
/execute as @a[scores={bad_omen=3,milk=1}] run effect give @s minecraft:bad_omen 999999 2
/execute as @a[scores={bad_omen=4,milk=1}] run effect give @s minecraft:bad_omen 999999 3
/execute as @a[scores={bad_omen=5,milk=1}] run effect give @s minecraft:bad_omen 999999 4
Step 3:
/scoreboard players set @a milk 0
/execute as @a unless entity @s[nbt={ActiveEffects:[{Id:31b}]}] run scoreboard players set @s bad_omen 0
Also, responding to your extra question, the way to dettect lvl is actually using Amplifier:<N>b
where N is the level of the effect starting from 0.
Avoiding clearing Hero of the Village
We will need:
/scoreboard objectives add HeroTime dummy
/scoreboard objectives add HeroLevel dummy
For that we do:
- Decrease one from the player HeroTime
- Check if he has HeroTime 0 and potion effect. If so, store his lvl and set his time to 24 minutes
- If he has HeroTime bigger than 0, reapply effect
- If his HeroTime is exactly 1, we clear the effect. This command needs to be at the end. As soon as the next cycle begins, the person with HeroTime of 1 will have 0 (Because of Step 1)
Translation:
Step 1:
/execute as @a[scores={HeroTime=1..}] run scoreboard players remove @s HeroTime 1
Step 2.1:
/execute as @a[nbt={ActiveEffects:[{Id:32b,Amplifier:0b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroLevel 0
/execute as @a[nbt={ActiveEffects:[{Id:32b,Amplifier:0b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroLevel 1
/execute as @a[nbt={ActiveEffects:[{Id:32b,Amplifier:0b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroLevel 2
/execute as @a[nbt={ActiveEffects:[{Id:32b,Amplifier:0b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroLevel 3
/execute as @a[nbt={ActiveEffects:[{Id:32b,Amplifier:0b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroLevel 4
Step 2.2:
/execute as @a[nbt={ActiveEffects:[{Id:32b}]}] unless score @s HeroTime matches 1.. run scoreboard players set @s HeroTime 28800
Step 3:
/execute as @a[scores={HeroTime=1..,HeroLevel=0}] run effect give @s minecraft:hero_of_the_village 9999 0
/execute as @a[scores={HeroTime=1..,HeroLevel=1}] run effect give @s minecraft:hero_of_the_village 9999 1
/execute as @a[scores={HeroTime=1..,HeroLevel=2}] run effect give @s minecraft:hero_of_the_village 9999 2
/execute as @a[scores={HeroTime=1..,HeroLevel=3}] run effect give @s minecraft:hero_of_the_village 9999 3
/execute as @a[scores={HeroTime=1..,HeroLevel=4}] run effect give @s minecraft:hero_of_the_village 9999 4
And step 4:
/execute as @a[scores={HeroTime=1}] run effect clear @s minecraft:hero_of_the_village