From 584e4865c32c6b53d16a316ee7b2adf3d45db762 Mon Sep 17 00:00:00 2001 From: Treetrain1 Date: Sat, 18 Nov 2023 18:37:19 -0600 Subject: [PATCH] sculk mixin changes + advancement fixes --- gradle.properties | 2 +- .../misc/mod_compat/FrozenLibIntegration.java | 22 ++- .../mixin/sculk/SculkBlockMixin.java | 160 +++++++++++------- .../tree/AbstractTreeGrowerMixin.java | 4 +- .../advancements/nether/all_effects.json | 64 ------- .../advancements/nether/all_potions.json | 50 ------ 6 files changed, 121 insertions(+), 181 deletions(-) delete mode 100644 src/main/resources/data/minecraft/advancements/nether/all_effects.json delete mode 100644 src/main/resources/data/minecraft/advancements/nether/all_potions.json diff --git a/gradle.properties b/gradle.properties index 769217f089..2a5d7f2e9a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ # Dependencies fabric_api_version=0.90.7+1.20.2 - mixin_extras_version=0.2.0 + mixin_extras_version=0.2.1-beta.2 fabric_asm_version=v2.3 frozenlib_version=1.4.2-mc1.20.2 diff --git a/src/main/java/net/frozenblock/wilderwild/misc/mod_compat/FrozenLibIntegration.java b/src/main/java/net/frozenblock/wilderwild/misc/mod_compat/FrozenLibIntegration.java index b229e4ba45..0809789ea4 100644 --- a/src/main/java/net/frozenblock/wilderwild/misc/mod_compat/FrozenLibIntegration.java +++ b/src/main/java/net/frozenblock/wilderwild/misc/mod_compat/FrozenLibIntegration.java @@ -49,6 +49,7 @@ import static net.frozenblock.wilderwild.registry.RegisterBlocks.*; import net.frozenblock.wilderwild.registry.RegisterEntities; import net.frozenblock.wilderwild.registry.RegisterItems; +import net.frozenblock.wilderwild.registry.RegisterMobEffects; import net.frozenblock.wilderwild.registry.RegisterSounds; import net.frozenblock.wilderwild.registry.RegisterWorldgen; import net.minecraft.advancements.Advancement; @@ -57,10 +58,12 @@ import net.minecraft.advancements.Criterion; import net.minecraft.advancements.critereon.BredAnimalsTrigger; import net.minecraft.advancements.critereon.ConsumeItemTrigger; +import net.minecraft.advancements.critereon.EffectsChangedTrigger; import net.minecraft.advancements.critereon.EntityPredicate; import net.minecraft.advancements.critereon.FilledBucketTrigger; import net.minecraft.advancements.critereon.ItemPredicate; import net.minecraft.advancements.critereon.LocationPredicate; +import net.minecraft.advancements.critereon.MobEffectsPredicate; import net.minecraft.advancements.critereon.PlayerTrigger; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceKey; @@ -211,7 +214,7 @@ public boolean test(LivingEntity entity) { addBiomeRequirement(advancement, RegisterWorldgen.OLD_GROWTH_DARK_FOREST); addBiomeRequirement(advancement, RegisterWorldgen.SNOWY_OLD_GROWTH_PINE_TAIGA); } - case "husbandry/balanced_diet" -> { + case "minecraft:husbandry/balanced_diet" -> { AdvancementAPI.addCriteria(advancement, "wilderwild:baobab_nut", CriteriaTriggers.CONSUME_ITEM.createCriterion( ConsumeItemTrigger.TriggerInstance.usedItem(RegisterItems.BAOBAB_NUT).triggerInstance()) ); @@ -241,7 +244,7 @@ public boolean test(LivingEntity entity) { }}) ); } - case "husbandry/bred_all_animals" -> { + case "minecraft:husbandry/bred_all_animals" -> { AdvancementAPI.addCriteria(advancement, "wilderwild:crab", CriteriaTriggers.BRED_ANIMALS.createCriterion( BredAnimalsTrigger.TriggerInstance.bredAnimals(EntityPredicate.Builder.entity().of(RegisterEntities.CRAB)).triggerInstance()) ); @@ -251,7 +254,7 @@ public boolean test(LivingEntity entity) { }}) ); } - case "husbandry/tactical_fishing" -> { + case "minecraft:husbandry/tactical_fishing" -> { AdvancementAPI.addCriteria(advancement, "wilderwild:crab_bucket", CriteriaTriggers.FILLED_BUCKET.createCriterion( FilledBucketTrigger.TriggerInstance.filledBucket(ItemPredicate.Builder.item().of(RegisterItems.CRAB_BUCKET)).triggerInstance()) ); @@ -265,9 +268,18 @@ public boolean test(LivingEntity entity) { }}) ); } - default -> { - } + case "minecraft:nether/all_potions", "minecraft:nether/all_effects" -> + AdvancementAPI.addCriteria( + advancement, + "wilderwild:reach_boost", + EffectsChangedTrigger.TriggerInstance.hasEffects( + MobEffectsPredicate.Builder.effects() + .and(RegisterMobEffects.REACH) + ) + ); + default -> {} } + } }); } diff --git a/src/main/java/net/frozenblock/wilderwild/mixin/sculk/SculkBlockMixin.java b/src/main/java/net/frozenblock/wilderwild/mixin/sculk/SculkBlockMixin.java index f9c65bc703..46f7c92e18 100644 --- a/src/main/java/net/frozenblock/wilderwild/mixin/sculk/SculkBlockMixin.java +++ b/src/main/java/net/frozenblock/wilderwild/mixin/sculk/SculkBlockMixin.java @@ -20,7 +20,9 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import java.util.Iterator; -import java.util.Optional; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.frozenblock.lib.math.api.EasyNoiseSampler; import net.frozenblock.wilderwild.block.OsseousSculkBlock; import net.frozenblock.wilderwild.block.sculk_behavior.SlabWallStairSculkBehavior; @@ -93,22 +95,7 @@ public abstract class SculkBlockMixin { private static final double WILDERWILD$OSSEOUS_SCULK_WORLD_GEN_THRESHOLD = 0.16; @Unique - private boolean wilderWild$isPlacingBelow; - - @Unique - private boolean wilderWild$canPlaceOsseousSculk; - @Unique - private BlockPos wilderWild$placementPos = null; - @Unique - private BlockState wilderWild$placementState = null; - @Unique - private Optional wilderWild$additionalGrowthCost = Optional.empty(); - @Unique - private boolean wilderWild$canPlace; - @Unique - private BlockPos wilderWild$placedPos; - @Unique - private BlockState wilderWild$placedState; + private volatile boolean wilderWild$canPlaceOsseousSculk; @Inject(method = "canPlaceGrowth", at = @At("HEAD"), cancellable = true) private static void wilderWild$canPlaceGrowth(LevelAccessor level, BlockPos pos, CallbackInfoReturnable info) { @@ -148,90 +135,145 @@ public abstract class SculkBlockMixin { } @ModifyExpressionValue(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SculkBlock;canPlaceGrowth(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;)Z")) - private boolean wilderWild$newWorldgenCharge(boolean original, SculkSpreader.@NotNull ChargeCursor chargeCursor, LevelAccessor levelAccessor, BlockPos blockPos, RandomSource randomSource, @NotNull SculkSpreader sculkSpreader, boolean bl) { - return this.wilderWild$canPlaceGrowth(levelAccessor, chargeCursor.getPos(), sculkSpreader.isWorldGeneration()) || original; + private boolean wilderWild$newWorldgenCharge( + boolean original, + SculkSpreader.@NotNull ChargeCursor chargeCursor, + LevelAccessor levelAccessor, + BlockPos blockPos, + RandomSource randomSource, + @NotNull SculkSpreader sculkSpreader, + boolean bl, + @Share("placingBelow") LocalBooleanRef placingBelow + ) { + return this.wilderWild$canPlaceGrowth(levelAccessor, chargeCursor.getPos(), sculkSpreader.isWorldGeneration(), placingBelow) || original; } @Inject(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SculkBlock;getRandomGrowthState(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/util/RandomSource;Z)Lnet/minecraft/world/level/block/state/BlockState;"), locals = LocalCapture.CAPTURE_FAILHARD) - private void wilderWild$getPlacementState(SculkSpreader.ChargeCursor charge, LevelAccessor level, BlockPos catalystPos, RandomSource random, @NotNull SculkSpreader sculkChargeHandler, boolean shouldConvertBlocks, CallbackInfoReturnable cir, int chargeAmount, BlockPos chargePos, int growthSpawnCost, BlockPos aboveChargePos) { - this.wilderWild$placementState = null; - this.wilderWild$placementPos = null; - this.wilderWild$additionalGrowthCost = Optional.empty(); + private void wilderWild$getPlacementState( + SculkSpreader.ChargeCursor charge, + LevelAccessor level, + BlockPos catalystPos, + RandomSource random, + @NotNull SculkSpreader sculkChargeHandler, + boolean shouldConvertBlocks, + CallbackInfoReturnable cir, + int chargeAmount, + BlockPos chargePos, + int growthSpawnCost, + BlockPos aboveChargePos, + @Share("placementPos") LocalRef placementPos, + @Share("placementState") LocalRef placementState, + @Share("placingBelow") LocalBooleanRef placingBelow, + @Share("additionalGrowthCost") LocalRef additionalGrowthCost, + @Share("canPlace") LocalBooleanRef canPlace + ) { + placementPos.set(null); + placementState.set(null); + additionalGrowthCost.set(null); boolean isWorldgen = sculkChargeHandler.isWorldGeneration(); - if (this.wilderWild$isPlacingBelow) { + if (placingBelow.get()) { BlockPos belowCharge = chargePos.below(); if (this.wilderWild$canPlaceOsseousSculk) { int pillarHeight = (int) Mth.clamp(EasyNoiseSampler.sample(EasyNoiseSampler.perlinXoro, belowCharge, WILDERWILD$RANDOMNESS, false, false) * WILDERWILD$HEIGHT_MULTIPLIER, 2, WILDERWILD$MAX_HEIGHT); - this.wilderWild$placementState = RegisterBlocks.OSSEOUS_SCULK.defaultBlockState().setValue(OsseousSculkBlock.HEIGHT_LEFT, pillarHeight).setValue(OsseousSculkBlock.TOTAL_HEIGHT, pillarHeight + 1).setValue(OsseousSculkBlock.FACING, Direction.DOWN); + placementState.set(RegisterBlocks.OSSEOUS_SCULK.defaultBlockState() + .setValue(OsseousSculkBlock.HEIGHT_LEFT, pillarHeight) + .setValue(OsseousSculkBlock.TOTAL_HEIGHT, pillarHeight + 1) + .setValue(OsseousSculkBlock.FACING, Direction.DOWN) + ); } else { - this.wilderWild$placementState = RegisterBlocks.HANGING_TENDRIL.defaultBlockState(); + placementState.set(RegisterBlocks.HANGING_TENDRIL.defaultBlockState()); } - this.wilderWild$placementPos = belowCharge; - this.wilderWild$additionalGrowthCost = Optional.of(1); + placementPos.set(belowCharge); + additionalGrowthCost.set(1); } - if (isWorldgen && this.wilderWild$placementState != null && this.wilderWild$placementState.is(RegisterBlocks.OSSEOUS_SCULK)) { - this.wilderWild$additionalGrowthCost = Optional.of(growthSpawnCost + 2); + if (isWorldgen && placementState.get() != null && placementState.get().is(RegisterBlocks.OSSEOUS_SCULK)) { + additionalGrowthCost.set(growthSpawnCost + 2); } BlockState chargePosState = level.getBlockState(chargePos); if ((isWorldgen && chargePosState.is(WilderBlockTags.SCULK_STAIR_REPLACEABLE_WORLDGEN)) || chargePosState.is(WilderBlockTags.SCULK_STAIR_REPLACEABLE)) { - this.wilderWild$placementState = RegisterBlocks.SCULK_STAIRS.withPropertiesOf(chargePosState); + placementState.set(RegisterBlocks.SCULK_STAIRS.withPropertiesOf(chargePosState)); } else if ((isWorldgen && chargePosState.is(WilderBlockTags.SCULK_SLAB_REPLACEABLE_WORLDGEN)) || chargePosState.is(WilderBlockTags.SCULK_SLAB_REPLACEABLE)) { - this.wilderWild$placementState = RegisterBlocks.SCULK_SLAB.withPropertiesOf(chargePosState); + placementState.set(RegisterBlocks.SCULK_SLAB.withPropertiesOf(chargePosState)); } else if ((isWorldgen && chargePosState.is(WilderBlockTags.SCULK_WALL_REPLACEABLE_WORLDGEN)) || chargePosState.is(WilderBlockTags.SCULK_WALL_REPLACEABLE)) { - this.wilderWild$placementState = RegisterBlocks.SCULK_WALL.withPropertiesOf(chargePosState); + placementState.set(RegisterBlocks.SCULK_WALL.withPropertiesOf(chargePosState)); } - this.wilderWild$canPlace = this.wilderWild$placementState != null && this.wilderWild$placementPos != null; + canPlace.set(placementState.get() != null && placementPos.get() != null); } @ModifyArgs(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelAccessor;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void wilderWild$newPlace(Args args) { - if (this.wilderWild$placementPos == null || this.wilderWild$placementState == null) { + private void wilderWild$newPlace( + Args args, + @Share("placementPos") LocalRef placementPos, + @Share("placementState") LocalRef placementState, + @Share("canPlace") LocalBooleanRef canPlace, + @Share("placedPos") LocalRef placedPos, + @Share("placedState") LocalRef placedState + ) { + if (placementPos.get() == null || placementState.get() == null) { return; } - if (this.wilderWild$canPlace) { - args.set(0, this.wilderWild$placementPos); - args.set(1, this.wilderWild$placementState); + if (canPlace.get()) { + args.set(0, placementPos.get()); + args.set(1, placementState.get()); } - this.wilderWild$placedPos = args.get(0); - this.wilderWild$placedState = args.get(1); + placedPos.set(args.get(0)); + placedState.set(args.get(1)); } @ModifyArgs(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelAccessor;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V")) - private void wilderWild$newSounds(Args args) { - if (this.wilderWild$placedPos == null || this.wilderWild$placedState == null) { + private void wilderWild$newSounds( + Args args, + @Share("placedPos") LocalRef placedPos, + @Share("placedState") LocalRef placedState + ) { + if (placedPos.get() == null || placedState.get() == null) { return; } - args.set(1, this.wilderWild$placedPos); - SoundType soundType = this.wilderWild$placedState.getSoundType(); + args.set(1, placedPos.get()); + SoundType soundType = placedState.get().getSoundType(); args.set(2, soundType.getPlaceSound()); args.set(4, soundType.getVolume()); args.set(5, soundType.getPitch()); } @Inject(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelAccessor;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V", shift = At.Shift.AFTER)) - private void wilderWild$handlePlacement(SculkSpreader.ChargeCursor chargeCursor, LevelAccessor levelAccessor, BlockPos blockPos, RandomSource randomSource, SculkSpreader sculkSpreader, boolean bl, CallbackInfoReturnable cir) { - if (this.wilderWild$placedState == null || this.wilderWild$placedPos == null) { + private void wilderWild$handlePlacement( + SculkSpreader.ChargeCursor chargeCursor, + LevelAccessor level, + BlockPos blockPos, + RandomSource randomSource, + SculkSpreader sculkSpreader, + boolean bl, + CallbackInfoReturnable cir, + @Share("placedPos") LocalRef placedPos, + @Share("placedState") LocalRef placedState + ) { + if (placedPos.get() == null || placedState.get() == null) { return; } - if (sculkSpreader.isWorldGeneration() && this.wilderWild$placedState.getBlock() instanceof OsseousSculkBlock osseousSculkBlock) { - int growthAmount = Math.max(0, this.wilderWild$placedState.getValue(OsseousSculkBlock.HEIGHT_LEFT)); + if (sculkSpreader.isWorldGeneration() && placedState.get().getBlock() instanceof OsseousSculkBlock osseousSculkBlock) { + int growthAmount = Math.max(0, placedState.get().getValue(OsseousSculkBlock.HEIGHT_LEFT)); for (int a = 0; a < growthAmount; a++) { - osseousSculkBlock.worldGenSpread(this.wilderWild$placedPos, levelAccessor, randomSource); + osseousSculkBlock.worldGenSpread(placedPos.get(), level, randomSource); } - } else if (this.wilderWild$placedState.is(RegisterBlocks.SCULK_STAIRS) || this.wilderWild$placedState.is(RegisterBlocks.SCULK_SLAB) || this.wilderWild$placedState.is(RegisterBlocks.SCULK_WALL)) { - SlabWallStairSculkBehavior.clearSculkVeins(levelAccessor, this.wilderWild$placedPos); + } else if (placedState.get().is(RegisterBlocks.SCULK_STAIRS) || placedState.get().is(RegisterBlocks.SCULK_SLAB) || placedState.get().is(RegisterBlocks.SCULK_WALL)) { + SlabWallStairSculkBehavior.clearSculkVeins(level, placedPos.get()); } - this.wilderWild$placedPos = null; - this.wilderWild$placedState = null; + placedPos.set(null); + placedState.set(null); } @ModifyExpressionValue(method = "attemptUseCharge", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(II)I")) - private int wilderWild$newReturnValue(int original) { - return this.wilderWild$additionalGrowthCost.map(integer -> original + integer).orElse(original); + private int wilderWild$newReturnValue( + int original, + @Share("additionalGrowthCost") LocalRef additionalGrowthCost + ) { + Integer additional = additionalGrowthCost.get(); + return additional != null ? original + additional : original; } @Inject(method = "getRandomGrowthState", at = @At(value = "RETURN", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) @@ -244,17 +286,17 @@ public abstract class SculkBlockMixin { } @Unique - private boolean wilderWild$canPlaceGrowth(@NotNull LevelAccessor level, @NotNull BlockPos pos, boolean isWorldGen) { + private boolean wilderWild$canPlaceGrowth(@NotNull LevelAccessor level, @NotNull BlockPos pos, boolean isWorldGen, LocalBooleanRef placingBelow) { this.wilderWild$canPlaceOsseousSculk = wilderWild$canPlaceOsseousSculk(pos, isWorldGen, level); if (level.getBlockState(pos).isFaceSturdy(level, pos, Direction.DOWN)) { BlockState blockState = level.getBlockState(pos.below()); Block block = blockState.getBlock(); if ((blockState.isAir() || block == Blocks.WATER || (this.wilderWild$canPlaceOsseousSculk && block == Blocks.LAVA) || block == Blocks.SCULK_VEIN) && level.getRandom().nextFloat() >= 0.75F) { - this.wilderWild$isPlacingBelow = true; + placingBelow.set(true); return true; } } - this.wilderWild$isPlacingBelow = false; + placingBelow.set(false); return false; } diff --git a/src/main/java/net/frozenblock/wilderwild/mixin/worldgen/tree/AbstractTreeGrowerMixin.java b/src/main/java/net/frozenblock/wilderwild/mixin/worldgen/tree/AbstractTreeGrowerMixin.java index c624699943..7d6dc9494f 100644 --- a/src/main/java/net/frozenblock/wilderwild/mixin/worldgen/tree/AbstractTreeGrowerMixin.java +++ b/src/main/java/net/frozenblock/wilderwild/mixin/worldgen/tree/AbstractTreeGrowerMixin.java @@ -35,10 +35,10 @@ public class AbstractTreeGrowerMixin implements AbstractTreeGrowerInterface { @Unique - private ServerLevel wilderWild$level; + private volatile ServerLevel wilderWild$level; @Unique - private BlockPos wilderWild$pos; + private volatile BlockPos wilderWild$pos; @Inject(method = "growTree", at = @At("HEAD")) public void wilderWild$growTree(ServerLevel level, ChunkGenerator generator, BlockPos pos, BlockState state, RandomSource random, CallbackInfoReturnable info) { diff --git a/src/main/resources/data/minecraft/advancements/nether/all_effects.json b/src/main/resources/data/minecraft/advancements/nether/all_effects.json deleted file mode 100644 index 2d9ddd1a3f..0000000000 --- a/src/main/resources/data/minecraft/advancements/nether/all_effects.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "parent": "minecraft:nether/all_potions", - "criteria": { - "all_effects": { - "conditions": { - "effects": { - "minecraft:absorption": {}, - "minecraft:bad_omen": {}, - "minecraft:blindness": {}, - "minecraft:conduit_power": {}, - "minecraft:darkness": {}, - "minecraft:dolphins_grace": {}, - "minecraft:fire_resistance": {}, - "minecraft:glowing": {}, - "minecraft:haste": {}, - "minecraft:hero_of_the_village": {}, - "minecraft:hunger": {}, - "minecraft:invisibility": {}, - "minecraft:jump_boost": {}, - "minecraft:levitation": {}, - "minecraft:mining_fatigue": {}, - "minecraft:nausea": {}, - "minecraft:night_vision": {}, - "minecraft:poison": {}, - "minecraft:regeneration": {}, - "minecraft:resistance": {}, - "minecraft:slow_falling": {}, - "minecraft:slowness": {}, - "minecraft:speed": {}, - "minecraft:strength": {}, - "minecraft:water_breathing": {}, - "minecraft:weakness": {}, - "minecraft:wither": {}, - "wilderwild:reach_boost": {} - } - }, - "trigger": "minecraft:effects_changed" - } - }, - "display": { - "announce_to_chat": true, - "description": { - "translate": "advancements.nether.all_effects.description" - }, - "frame": "challenge", - "hidden": true, - "icon": { - "item": "minecraft:bucket" - }, - "show_toast": true, - "title": { - "translate": "advancements.nether.all_effects.title" - } - }, - "requirements": [ - [ - "all_effects" - ] - ], - "rewards": { - "experience": 1000 - }, - "sends_telemetry_event": true -} diff --git a/src/main/resources/data/minecraft/advancements/nether/all_potions.json b/src/main/resources/data/minecraft/advancements/nether/all_potions.json deleted file mode 100644 index f59345b6df..0000000000 --- a/src/main/resources/data/minecraft/advancements/nether/all_potions.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "parent": "minecraft:nether/brew_potion", - "criteria": { - "all_effects": { - "conditions": { - "effects": { - "minecraft:fire_resistance": {}, - "minecraft:invisibility": {}, - "minecraft:jump_boost": {}, - "minecraft:night_vision": {}, - "minecraft:poison": {}, - "minecraft:regeneration": {}, - "minecraft:resistance": {}, - "minecraft:slow_falling": {}, - "minecraft:slowness": {}, - "minecraft:speed": {}, - "minecraft:strength": {}, - "minecraft:water_breathing": {}, - "minecraft:weakness": {}, - "wilderwild:reach_boost": {} - } - }, - "trigger": "minecraft:effects_changed" - } - }, - "display": { - "announce_to_chat": true, - "description": { - "translate": "advancements.nether.all_potions.description" - }, - "frame": "challenge", - "hidden": false, - "icon": { - "item": "minecraft:milk_bucket" - }, - "show_toast": true, - "title": { - "translate": "advancements.nether.all_potions.title" - } - }, - "requirements": [ - [ - "all_effects" - ] - ], - "rewards": { - "experience": 100 - }, - "sends_telemetry_event": true -}