Skip to content

Commit

Permalink
Expand powdered snow advancement to check modded armor (#1202)
Browse files Browse the repository at this point in the history
  • Loading branch information
pupnewfster authored Jul 1, 2024
1 parent 16d7de6 commit 5b4b9b6
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"parent": "minecraft:adventure/sleep_in_bed",
"criteria": {
"walk_on_powder_snow_with_leather_boots": {
"conditions": {
"player": [
{
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"stepping_on": {
"block": {
"blocks": "minecraft:powder_snow"
}
},
"type_specific": {
"type": "neoforge:snow_boots"
}
}
}
]
},
"trigger": "minecraft:location"
}
},
"display": {
"description": {
"translate": "advancements.adventure.walk_on_powder_snow_with_leather_boots.description"
},
"icon": {
"count": 1,
"id": "minecraft:leather_boots"
},
"title": {
"translate": "advancements.adventure.walk_on_powder_snow_with_leather_boots.title"
}
},
"requirements": [
[
"walk_on_powder_snow_with_leather_boots"
]
],
"sends_telemetry_event": true
}
2 changes: 2 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import net.neoforged.neoforge.common.advancements.critereon.ItemAbilityPredicate;
import net.neoforged.neoforge.common.advancements.critereon.PiglinCurrencyItemPredicate;
import net.neoforged.neoforge.common.advancements.critereon.PiglinNeutralArmorEntityPredicate;
import net.neoforged.neoforge.common.advancements.critereon.SnowBootsEntityPredicate;
import net.neoforged.neoforge.common.conditions.AndCondition;
import net.neoforged.neoforge.common.conditions.FalseCondition;
import net.neoforged.neoforge.common.conditions.ICondition;
Expand Down Expand Up @@ -394,6 +395,7 @@ public class NeoForgeMod {

private static final DeferredRegister<MapCodec<? extends EntitySubPredicate>> ENTITY_PREDICATE_CODECS = DeferredRegister.create(Registries.ENTITY_SUB_PREDICATE_TYPE, NeoForgeVersion.MOD_ID);
public static final DeferredHolder<MapCodec<? extends EntitySubPredicate>, MapCodec<PiglinNeutralArmorEntityPredicate>> PIGLIN_NEUTRAL_ARMOR_PREDICATE = ENTITY_PREDICATE_CODECS.register("piglin_neutral_armor", () -> PiglinNeutralArmorEntityPredicate.CODEC);
public static final DeferredHolder<MapCodec<? extends EntitySubPredicate>, MapCodec<SnowBootsEntityPredicate>> SNOW_BOOTS_PREDICATE = ENTITY_PREDICATE_CODECS.register("snow_boots", () -> SnowBootsEntityPredicate.CODEC);

private static final DeferredRegister<ItemSubPredicate.Type<?>> ITEM_SUB_PREDICATES = DeferredRegister.create(Registries.ITEM_SUB_PREDICATE_TYPE, NeoForgeVersion.MOD_ID);
public static final DeferredHolder<ItemSubPredicate.Type<?>, ItemSubPredicate.Type<ItemAbilityPredicate>> ITEM_ABILITY_PREDICATE = ITEM_SUB_PREDICATES.register("item_ability", () -> ItemAbilityPredicate.TYPE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common.advancements.critereon;

import com.mojang.serialization.MapCodec;
import net.minecraft.advancements.critereon.EntitySubPredicate;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;

public class SnowBootsEntityPredicate implements EntitySubPredicate {
public static final SnowBootsEntityPredicate INSTANCE = new SnowBootsEntityPredicate();
public static final MapCodec<SnowBootsEntityPredicate> CODEC = MapCodec.unit(INSTANCE);

private SnowBootsEntityPredicate() {}

@Override
public MapCodec<SnowBootsEntityPredicate> codec() {
return CODEC;
}

@Override
public boolean matches(Entity entity, ServerLevel level, @Nullable Vec3 position) {
return entity instanceof LivingEntity living && living.getItemBySlot(EquipmentSlot.FEET).canWalkOnPowderedSnow(living);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.minecraft.advancements.critereon.ContextAwarePredicate;
import net.minecraft.advancements.critereon.EntityEquipmentPredicate;
import net.minecraft.advancements.critereon.EntityPredicate;
import net.minecraft.advancements.critereon.EntitySubPredicate;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.ItemUsedOnLocationTrigger;
import net.minecraft.advancements.critereon.PlayerInteractTrigger;
Expand All @@ -49,6 +50,7 @@
import net.neoforged.neoforge.common.advancements.critereon.ItemAbilityPredicate;
import net.neoforged.neoforge.common.advancements.critereon.PiglinCurrencyItemPredicate;
import net.neoforged.neoforge.common.advancements.critereon.PiglinNeutralArmorEntityPredicate;
import net.neoforged.neoforge.common.advancements.critereon.SnowBootsEntityPredicate;
import net.neoforged.neoforge.common.data.AdvancementProvider;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import org.jetbrains.annotations.Nullable;
Expand All @@ -63,7 +65,7 @@ private static List<AdvancementGenerator> getVanillaAdvancementProviders(PackOut
criteriaReplacers.add(replaceMatchToolCriteria(ItemAbilities.AXE_WAX_OFF, getPrivateValue(VanillaHusbandryAdvancements.class, null, "WAX_SCRAPING_TOOLS")));
criteriaReplacers.add(replaceInteractCriteria(ItemPredicate.Builder.item().withSubPredicate(ItemAbilityPredicate.TYPE, new ItemAbilityPredicate(ItemAbilities.SHEARS_REMOVE_ARMOR)).build(), Items.SHEARS));
criteriaReplacers.add(replaceInteractCriteria(ItemPredicate.Builder.item().withSubPredicate(PiglinCurrencyItemPredicate.TYPE, PiglinCurrencyItemPredicate.INSTANCE).build(), PiglinAi.BARTERING_ITEM));
criteriaReplacers.add(replaceWearingPredicate(EntityPredicate.Builder.entity().subPredicate(PiglinNeutralArmorEntityPredicate.INSTANCE).build(), predicate -> {
criteriaReplacers.add(replaceWearingPredicate(PiglinNeutralArmorEntityPredicate.INSTANCE, predicate -> {
if (predicate.head().filter(item -> predicateMatches(item, Items.GOLDEN_HELMET)).isPresent()) {
return true;
} else if (predicate.chest().filter(item -> predicateMatches(item, Items.GOLDEN_CHESTPLATE)).isPresent()) {
Expand All @@ -73,6 +75,8 @@ private static List<AdvancementGenerator> getVanillaAdvancementProviders(PackOut
}
return predicate.feet().filter(item -> predicateMatches(item, Items.GOLDEN_BOOTS)).isPresent();
}));
//Walk on powdered snow
criteriaReplacers.add(replaceWearingPredicate(SnowBootsEntityPredicate.INSTANCE, predicate -> predicate.feet().filter(item -> predicateMatches(item, Items.LEATHER_BOOTS)).isPresent()));

List<AdvancementSubProvider> subProviders = getPrivateValue(net.minecraft.data.advancements.AdvancementProvider.class, VanillaAdvancementProvider.create(output, registries), "subProviders");
return subProviders.stream()
Expand Down Expand Up @@ -123,17 +127,42 @@ private static boolean predicateMatches(ItemPredicate predicate, ItemLike... tar
return true;
}

private static BiFunction<Criterion<?>, HolderLookup.Provider, Criterion<?>> replaceWearingPredicate(EntityPredicate replacement, Predicate<EntityEquipmentPredicate> shouldReplace) {
private static BiFunction<Criterion<?>, HolderLookup.Provider, Criterion<?>> replaceWearingPredicate(EntitySubPredicate subPredicate, Predicate<EntityEquipmentPredicate> shouldReplace) {
return replacePlayerPredicate(condition -> {
boolean invert = false;
if (condition instanceof InvertedLootItemCondition inverted) {
if (inverted.term() instanceof LootItemEntityPropertyCondition entityPropertyCondition) {
Optional<EntityPredicate> predicate = entityPropertyCondition.predicate();
if (predicate.isPresent()) {
EntityPredicate entityPredicate = predicate.get();
if (entityPredicate.equipment().filter(shouldReplace).isPresent()) {
//Note: We as currently there are no issues, we just skip any cases where other fields in the entity predicate are present
return LootItemEntityPropertyCondition.hasProperties(entityPropertyCondition.entityTarget(), replacement).invert().build();
condition = inverted.term();
invert = true;
}
if (condition instanceof LootItemEntityPropertyCondition entityPropertyCondition) {
Optional<EntityPredicate> predicate = entityPropertyCondition.predicate();
if (predicate.isPresent()) {
EntityPredicate entityPredicate = predicate.get();
if (entityPredicate.equipment().filter(shouldReplace).isPresent()) {
if (entityPredicate.subPredicate().isPresent()) {
throw new IllegalStateException("Attempting to replace an entity predicate that already has a sub predicate");
}
EntityPredicate replacement = new EntityPredicate(
entityPredicate.entityType(),
entityPredicate.distanceToPlayer(),
entityPredicate.movement(),
entityPredicate.location(),
entityPredicate.effects(),
entityPredicate.nbt(),
entityPredicate.flags(),
Optional.empty(),
Optional.of(subPredicate),
entityPredicate.periodicTick(),
entityPredicate.vehicle(),
entityPredicate.passenger(),
entityPredicate.targetedEntity(),
entityPredicate.team(),
entityPredicate.slots());
LootItemCondition.Builder conditionBuilder = LootItemEntityPropertyCondition.hasProperties(entityPropertyCondition.entityTarget(), replacement);
if (invert) {
return conditionBuilder.invert().build();
}
return conditionBuilder.build();
}
}
}
Expand Down

0 comments on commit 5b4b9b6

Please sign in to comment.