Skip to content

Commit

Permalink
Implement support for preventing effects from being removed by milk o…
Browse files Browse the repository at this point in the history
…r totems
  • Loading branch information
XFactHD committed Oct 18, 2024
1 parent 71955d3 commit 0bc0638
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 38 deletions.
17 changes: 17 additions & 0 deletions patches/net/minecraft/world/item/component/Consumables.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--- a/net/minecraft/world/item/component/Consumables.java
+++ b/net/minecraft/world/item/component/Consumables.java
@@ -62,7 +_,13 @@
public static final Consumable SPIDER_EYE = defaultFood()
.onConsume(new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.POISON, 100, 0)))
.build();
- public static final Consumable MILK_BUCKET = defaultDrink().onConsume(ClearAllStatusEffectsConsumeEffect.INSTANCE).build();
+ public static final Consumable MILK_BUCKET = defaultDrink().onConsume(new RemoveStatusEffectsConsumeEffect(new net.neoforged.neoforge.registries.holdersets.NotHolderSet<>(
+ net.minecraft.core.registries.BuiltInRegistries.MOB_EFFECT,
+ new net.neoforged.neoforge.registries.holdersets.LazyNamedHolderSet<>(
+ net.minecraft.core.registries.BuiltInRegistries.MOB_EFFECT,
+ net.neoforged.neoforge.common.Tags.MobEffects.NOT_MILK_CURABLE
+ )
+ ))).build();
public static final Consumable CHORUS_FRUIT = defaultFood().onConsume(new TeleportRandomlyConsumeEffect()).build();

public static Consumable.Builder defaultFood() {
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--- a/net/minecraft/world/item/component/DeathProtection.java
+++ b/net/minecraft/world/item/component/DeathProtection.java
@@ -25,7 +_,13 @@
);
public static final DeathProtection TOTEM_OF_UNDYING = new DeathProtection(
List.of(
- new ClearAllStatusEffectsConsumeEffect(),
+ new net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect(new net.neoforged.neoforge.registries.holdersets.NotHolderSet<>(
+ net.minecraft.core.registries.BuiltInRegistries.MOB_EFFECT,
+ new net.neoforged.neoforge.registries.holdersets.LazyNamedHolderSet<>(
+ net.minecraft.core.registries.BuiltInRegistries.MOB_EFFECT,
+ net.neoforged.neoforge.common.Tags.MobEffects.NOT_TOTEM_CURABLE
+ )
+ )),
new ApplyStatusEffectsConsumeEffect(
List.of(
new MobEffectInstance(MobEffects.REGENERATION, 900, 1),
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": []
}
10 changes: 10 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderSet;
import net.minecraft.core.RegistryCodecs;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.core.registries.Registries;
Expand Down Expand Up @@ -115,6 +116,7 @@
import net.neoforged.neoforge.common.data.internal.NeoForgeItemTagsProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeLanguageProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeLootTableProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeMobEffectsTagsProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeRecipeProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeRegistryOrderReportProvider;
import net.neoforged.neoforge.common.data.internal.NeoForgeSpriteSourceProvider;
Expand Down Expand Up @@ -161,6 +163,7 @@
import net.neoforged.neoforge.registries.holdersets.AndHolderSet;
import net.neoforged.neoforge.registries.holdersets.AnyHolderSet;
import net.neoforged.neoforge.registries.holdersets.HolderSetType;
import net.neoforged.neoforge.registries.holdersets.LazyNamedHolderSet;
import net.neoforged.neoforge.registries.holdersets.NotHolderSet;
import net.neoforged.neoforge.registries.holdersets.OrHolderSet;
import net.neoforged.neoforge.server.command.EnumArgument;
Expand Down Expand Up @@ -353,6 +356,12 @@ public class NeoForgeMod {
*/
public static final Holder<HolderSetType> NOT_HOLDER_SET = HOLDER_SET_TYPES.register("not", NotHolderSet.Type::new);

/**
* Stock holder set type that represents the values of the tag it is constructed from. Intended for cases where a tag needs to be specified as a holder set in a context
* where directly getting a {@link HolderSet.Named} from a registry is not possible.
*/
public static final Holder<HolderSetType> LAZY_NAMED_HOLDER_SET = HOLDER_SET_TYPES.register("lazy_named", LazyNamedHolderSet.Type::new);

private static final DeferredRegister<IngredientType<?>> INGREDIENT_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.INGREDIENT_TYPES, NeoForgeVersion.MOD_ID);

public static final DeferredHolder<IngredientType<?>, IngredientType<CompoundIngredient>> COMPOUND_INGREDIENT_TYPE = INGREDIENT_TYPES.register("compound", () -> new IngredientType<>(CompoundIngredient.CODEC));
Expand Down Expand Up @@ -626,6 +635,7 @@ public void gatherData(GatherDataEvent event) {
gen.addProvider(event.includeServer(), new NeoForgeDamageTypeTagsProvider(packOutput, lookupProvider, existingFileHelper));
gen.addProvider(event.includeServer(), new NeoForgeRegistryOrderReportProvider(packOutput));
gen.addProvider(event.includeServer(), new NeoForgeDataMapsProvider(packOutput, lookupProvider));
gen.addProvider(event.includeServer(), new NeoForgeMobEffectsTagsProvider(packOutput, lookupProvider, existingFileHelper));

gen.addProvider(event.includeClient(), new NeoForgeSpriteSourceProvider(packOutput, lookupProvider, existingFileHelper));
gen.addProvider(event.includeClient(), new VanillaSoundDefinitionsProvider(packOutput, existingFileHelper));
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/Tags.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
Expand Down Expand Up @@ -1162,6 +1163,16 @@ private static TagKey<DamageType> neoforgeTag(String name) {
}
}

public static class MobEffects {
public static final TagKey<MobEffect> NOT_MILK_CURABLE = neoforgeTag("not_milk_curable");

public static final TagKey<MobEffect> NOT_TOTEM_CURABLE = neoforgeTag("not_totem_curable");

private static TagKey<MobEffect> neoforgeTag(String name) {
return TagKey.create(Registries.MOB_EFFECT, ResourceLocation.fromNamespaceAndPath("neoforge", name));
}
}

/**
* Use this to get a TagKey's translation key safely on any side.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common.data.internal;

import java.util.concurrent.CompletableFuture;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.TagsProvider;
import net.minecraft.world.effect.MobEffect;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import org.jetbrains.annotations.Nullable;

public final class NeoForgeMobEffectsTagsProvider extends TagsProvider<MobEffect> {
public NeoForgeMobEffectsTagsProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper fileHelper) {
super(output, Registries.MOB_EFFECT, lookupProvider, NeoForgeVersion.MOD_ID, fileHelper);
}

@Override
protected void addTags(HolderLookup.Provider lookupProvider) {
tag(Tags.MobEffects.NOT_MILK_CURABLE);
tag(Tags.MobEffects.NOT_TOTEM_CURABLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries.holdersets;

import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderOwner;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import net.minecraft.util.RandomSource;
import net.neoforged.neoforge.common.NeoForgeMod;
import org.jetbrains.annotations.Nullable;

public final class LazyNamedHolderSet<T> implements ICustomHolderSet<T> {
private final List<Runnable> owners = new ArrayList<>();
private final HolderLookup.RegistryLookup<T> registryLookup;
private final TagKey<T> tagKey;
@Nullable
private HolderSet.Named<T> resolvedSet;

public LazyNamedHolderSet(HolderLookup.RegistryLookup<T> registryLookup, TagKey<T> tagKey) {
this.registryLookup = registryLookup;
this.tagKey = tagKey;
}

public HolderLookup.RegistryLookup<T> registryLookup() {
return registryLookup;
}

public TagKey<T> tagKey() {
return tagKey;
}

@Override
public HolderSetType type() {
return NeoForgeMod.LAZY_NAMED_HOLDER_SET.value();
}

@Override
public void addInvalidationListener(Runnable runnable) {
this.owners.add(runnable);
}

@Override
public Stream<Holder<T>> stream() {
return resolve().stream();
}

@Override
public int size() {
return resolve().size();
}

@Override
public boolean isBound() {
return resolve().isBound();
}

@Override
public Either<TagKey<T>, List<Holder<T>>> unwrap() {
return resolve().unwrap();
}

@Override
public Optional<Holder<T>> getRandomElement(RandomSource random) {
return resolve().getRandomElement(random);
}

@Override
public Holder<T> get(int idx) {
return resolve().get(idx);
}

@Override
public boolean contains(Holder<T> holder) {
return resolve().contains(holder);
}

@Override
public boolean canSerializeIn(HolderOwner<T> owner) {
return resolve().canSerializeIn(owner);
}

@Override
public Optional<TagKey<T>> unwrapKey() {
return resolve().unwrapKey();
}

@Override
public Iterator<Holder<T>> iterator() {
return resolve().iterator();
}

@Override
public String toString() {
return "LazyNamedHolderSet(" + this.tagKey + ")";
}

private HolderSet.Named<T> resolve() {
HolderSet.Named<T> resolved = this.resolvedSet;
if (resolved == null) {
this.resolvedSet = resolved = this.registryLookup.getOrThrow(this.tagKey);
resolved.addInvalidationListener(this::invalidate);
}
return resolved;
}

private void invalidate() {
this.resolvedSet = null;
for (Runnable runnable : this.owners) {
runnable.run();
}
}

public static final class Type implements HolderSetType {
@Override
public <T> MapCodec<? extends ICustomHolderSet<T>> makeCodec(ResourceKey<? extends Registry<T>> registryKey, Codec<Holder<T>> holderCodec, boolean forceList) {
return RecordCodecBuilder.<LazyNamedHolderSet<T>>mapCodec(
builder -> builder.group(
RegistryOps.retrieveRegistryLookup(registryKey).forGetter(LazyNamedHolderSet::registryLookup),
TagKey.hashedCodec(registryKey).fieldOf("tag").forGetter(LazyNamedHolderSet::tagKey))
.apply(builder, LazyNamedHolderSet::new));
}

@Override
public <T> StreamCodec<RegistryFriendlyByteBuf, LazyNamedHolderSet<T>> makeStreamCodec(ResourceKey<? extends Registry<T>> registryKey) {
return new StreamCodec<>() {
private final StreamCodec<ByteBuf, TagKey<T>> keyCodec = TagKey.streamCodec(registryKey);

@Override
public LazyNamedHolderSet<T> decode(RegistryFriendlyByteBuf buf) {
return new LazyNamedHolderSet<>(buf.registryAccess().lookupOrThrow(registryKey), keyCodec.decode(buf));
}

@Override
public void encode(RegistryFriendlyByteBuf buf, LazyNamedHolderSet<T> set) {
keyCodec.encode(buf, set.tagKey);
}
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"values": [
"neotests_effect_cures:test_effect"
]
}
Loading

0 comments on commit 0bc0638

Please sign in to comment.