Skip to content

Commit

Permalink
[1.20.4] Rework how effects determine what they can be cured by (#350)
Browse files Browse the repository at this point in the history
Fixes #322
  • Loading branch information
XFactHD authored Dec 16, 2023
1 parent e851e60 commit 52cd634
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 219 deletions.

This file was deleted.

This file was deleted.

31 changes: 0 additions & 31 deletions .teamcity/patches/projects/_Self.kts

This file was deleted.

90 changes: 46 additions & 44 deletions patches/net/minecraft/world/effect/MobEffectInstance.java.patch
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
--- a/net/minecraft/world/effect/MobEffectInstance.java
+++ b/net/minecraft/world/effect/MobEffectInstance.java
@@ -19,7 +_,7 @@
import net.minecraft.world.entity.LivingEntity;
import org.slf4j.Logger;
@@ -78,6 +_,7 @@
this.showIcon = p_216892_;
this.hiddenEffect = p_216893_;
this.factorData = p_216894_;
+ this.effect.fillEffectCures(this.cures, this);
}

-public class MobEffectInstance implements Comparable<MobEffectInstance> {
+public class MobEffectInstance implements Comparable<MobEffectInstance>, net.neoforged.neoforge.common.extensions.IMobEffectInstanceExtension {
private static final Logger LOGGER = LogUtils.getLogger();
public static final int INFINITE_DURATION = -1;
private static final String TAG_ID = "id";
@@ -96,6 +_,7 @@
public MobEffectInstance(MobEffectInstance p_19543_) {
@@ -96,6 +_,8 @@
this.ambient = p_19549_.ambient;
this.visible = p_19549_.visible;
this.showIcon = p_19549_.showIcon;
+ this.curativeItems = p_19549_.curativeItems == null ? null : new java.util.ArrayList<net.minecraft.world.item.ItemStack>(p_19549_.curativeItems);
+ this.cures.clear();
+ this.cures.addAll(p_19549_.cures);
}

public boolean update(MobEffectInstance p_19559_) {
Expand All @@ -25,64 +25,66 @@
this.writeDetailsTo(p_19556_);
return p_19556_;
}
@@ -287,6 +_,7 @@
this.hiddenEffect.save(compoundtag);
p_19568_.put("hidden_effect", compoundtag);
}
+ writeCurativeItems(p_19568_);
@@ -295,6 +_,8 @@
.resultOrPartial(LOGGER::error)
.ifPresent(p_216906_ -> p_19568_.put("factor_calculation_data", p_216906_))
);
+
+ writeCures(p_19568_);
}

this.factorData
.ifPresent(
@@ -332,9 +_,9 @@
@Nullable
@@ -332,7 +_,7 @@
optional = Optional.empty();
}

- return new MobEffectInstance(p_19546_, j, Math.max(i, 0), flag, flag1, flag2, mobeffectinstance, optional);
+ return readCurativeItems(new MobEffectInstance(p_19546_, j, Math.max(0, i), flag, flag1, flag2, mobeffectinstance, optional), p_19547_);
+ return new MobEffectInstance(p_19546_, j, Math.max(i, 0), flag, flag1, flag2, mobeffectinstance, optional).readCures(p_19547_);
}
-
+

public int compareTo(MobEffectInstance p_19566_) {
int i = 32147;
return (this.getDuration() <= 32147 || p_19566_.getDuration() <= 32147) && (!this.isAmbient() || !p_19566_.isAmbient())
@@ -342,12 +_,38 @@
@@ -342,12 +_,42 @@
.compareFalseFirst(this.isAmbient(), p_19566_.isAmbient())
.compareFalseFirst(this.isInfiniteDuration(), p_19566_.isInfiniteDuration())
.compare(this.getDuration(), p_19566_.getDuration())
- .compare(this.getEffect().getColor(), p_19566_.getEffect().getColor())
+ .compare(this.getEffect().getSortOrder(this), p_19566_.getEffect().getSortOrder(this))
+ .compare(this.getEffect().getSortOrder(this), p_19566_.getEffect().getSortOrder(p_19566_))
.result()
: ComparisonChain.start()
.compare(this.isAmbient(), p_19566_.isAmbient())
- .compare(this.getEffect().getColor(), p_19566_.getEffect().getColor())
+ .compare(this.getEffect().getSortOrder(this), p_19566_.getEffect().getSortOrder(this))
+ .compare(this.getEffect().getSortOrder(this), p_19566_.getEffect().getSortOrder(p_19566_))
.result();
+ }
+
+ //======================= FORGE START ===========================
+ private java.util.List<net.minecraft.world.item.ItemStack> curativeItems;
+ private final java.util.Set<net.neoforged.neoforge.common.EffectCure> cures = com.google.common.collect.Sets.newIdentityHashSet();
+
+ @Override
+ public java.util.List<net.minecraft.world.item.ItemStack> getCurativeItems() {
+ if (this.curativeItems == null) //Lazy load this so that we don't create a circular dep on Items.
+ this.curativeItems = getEffect().getCurativeItems();
+ return this.curativeItems;
+ /**
+ * {@return the {@link net.neoforged.neoforge.common.EffectCure}s which can cure the {@link MobEffect} held by this {@link MobEffectInstance}}
+ */
+ public java.util.Set<net.neoforged.neoforge.common.EffectCure> getCures() {
+ return cures;
+ }
+ @Override
+ public void setCurativeItems(java.util.List<net.minecraft.world.item.ItemStack> curativeItems) {
+ this.curativeItems = curativeItems;
+ }
+ private static MobEffectInstance readCurativeItems(MobEffectInstance effect, CompoundTag nbt) {
+ if (nbt.contains("CurativeItems", net.minecraft.nbt.Tag.TAG_LIST)) {
+ java.util.List<net.minecraft.world.item.ItemStack> items = new java.util.ArrayList<net.minecraft.world.item.ItemStack>();
+ net.minecraft.nbt.ListTag list = nbt.getList("CurativeItems", net.minecraft.nbt.Tag.TAG_COMPOUND);
+
+ private MobEffectInstance readCures(CompoundTag tag) {
+ cures.clear(); // Overwrite cures with ones stored in NBT, if any
+ if (tag.contains("neoforge:cures", Tag.TAG_LIST)) {
+ net.minecraft.nbt.ListTag list = tag.getList("neoforge:cures", Tag.TAG_STRING);
+ for (int i = 0; i < list.size(); i++) {
+ items.add(net.minecraft.world.item.ItemStack.of(list.getCompound(i)));
+ cures.add(net.neoforged.neoforge.common.EffectCure.get(list.getString(i)));
+ }
+ effect.setCurativeItems(items);
+ }
+ return this;
+ }
+
+ return effect;
+ private void writeCures(CompoundTag tag) {
+ if (!cures.isEmpty()) {
+ net.minecraft.nbt.ListTag list = new net.minecraft.nbt.ListTag();
+ for (net.neoforged.neoforge.common.EffectCure cure : cures) {
+ list.add(net.minecraft.nbt.StringTag.valueOf(cure.name()));
+ }
+ tag.put("neoforge:cures", list);
+ }
}

public static class FactorData {
21 changes: 14 additions & 7 deletions patches/net/minecraft/world/entity/LivingEntity.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
for(flag = false; iterator.hasNext(); flag = true) {
- this.onEffectRemoved(iterator.next());
+ MobEffectInstance effect = iterator.next();
+ if(net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.living.MobEffectEvent.Remove(this, effect)).isCanceled()) continue;
+ if(net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, effect, null)) continue;
+ this.onEffectRemoved(effect);
iterator.remove();
}
Expand All @@ -131,7 +131,7 @@
}

public boolean removeEffect(MobEffect p_21196_) {
+ if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.living.MobEffectEvent.Remove(this, p_21196_)).isCanceled()) return false;
+ if (net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, p_21196_, null)) return false;
MobEffectInstance mobeffectinstance = this.removeEffectNoUpdate(p_21196_);
if (mobeffectinstance != null) {
this.onEffectRemoved(mobeffectinstance);
Expand Down Expand Up @@ -212,7 +212,7 @@
itemstack = itemstack1.copy();
itemstack1.shrink(1);
break;
@@ -1254,7 +_,7 @@
@@ -1254,13 +_,13 @@

if (itemstack != null) {
if (this instanceof ServerPlayer serverplayer) {
Expand All @@ -221,6 +221,13 @@
CriteriaTriggers.USED_TOTEM.trigger(serverplayer, itemstack);
this.gameEvent(GameEvent.ITEM_INTERACT_FINISH);
}

this.setHealth(1.0F);
- this.removeAllEffects();
+ this.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.PROTECTED_BY_TOTEM);
this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1));
this.addEffect(new MobEffectInstance(MobEffects.ABSORPTION, 100, 1));
this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 800, 0));
@@ -1328,6 +_,7 @@
}

Expand Down Expand Up @@ -669,17 +676,17 @@

+ /* ==== FORGE START ==== */
+ /***
+ * Removes all potion effects that have curativeItem as a curative item for its effect
+ * @param curativeItem The itemstack we are using to cure potion effects
+ * Removes all potion effects that have the given {@link net.neoforged.neoforge.common.EffectCure} in their set of cures
+ * @param cure the EffectCure being used
+ */
+ public boolean curePotionEffects(ItemStack curativeItem) {
+ public boolean removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCure cure) {
+ if (this.level().isClientSide)
+ return false;
+ boolean ret = false;
+ Iterator<MobEffectInstance> itr = this.activeEffects.values().iterator();
+ while (itr.hasNext()) {
+ MobEffectInstance effect = itr.next();
+ if (effect.isCurativeItem(curativeItem) && !net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.living.MobEffectEvent.Remove(this, effect)).isCanceled()) {
+ if (effect.getCures().contains(cure) && !net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, effect, cure)) {
+ this.onEffectRemoved(effect);
+ itr.remove();
+ ret = true;
Expand Down
11 changes: 11 additions & 0 deletions patches/net/minecraft/world/item/HoneyBottleItem.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/net/minecraft/world/item/HoneyBottleItem.java
+++ b/net/minecraft/world/item/HoneyBottleItem.java
@@ -28,7 +_,7 @@
}

if (!p_41349_.isClientSide) {
- p_41350_.removeEffect(MobEffects.POISON);
+ p_41350_.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.HONEY);
}

if (p_41348_.isEmpty()) {
12 changes: 3 additions & 9 deletions patches/net/minecraft/world/item/MilkBucketItem.java.patch
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
--- a/net/minecraft/world/item/MilkBucketItem.java
+++ b/net/minecraft/world/item/MilkBucketItem.java
@@ -22,13 +_,10 @@
CriteriaTriggers.CONSUME_ITEM.trigger(serverplayer, p_42923_);
serverplayer.awardStat(Stats.ITEM_USED.get(this));
@@ -28,7 +_,7 @@
}
+ if (!p_42924_.isClientSide) p_42925_.curePotionEffects(p_42923_); // FORGE - move up so stack.shrink does not turn stack into air

if (p_42925_ instanceof Player && !((Player)p_42925_).getAbilities().instabuild) {
p_42923_.shrink(1);
- }
-
- if (!p_42924_.isClientSide) {
if (!p_42924_.isClientSide) {
- p_42925_.removeAllEffects();
+ p_42925_.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.MILK);
}

return p_42923_.isEmpty() ? new ItemStack(Items.BUCKET) : p_42923_;
65 changes: 65 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/EffectCure.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common;

import com.mojang.serialization.Codec;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.neoforged.neoforge.event.entity.living.MobEffectEvent;

/**
* Defines a cure that is used to remove {@link MobEffect}s from a {@link LivingEntity}.
* <p>Cures can be added to or removed from your own effects via {@link MobEffect#fillEffectCures(Set, MobEffectInstance)}
* or any effect by modifying the set of cures on the {@link MobEffectInstance} in {@link MobEffectEvent.Added}
*/
public final class EffectCure {
private static final Map<String, EffectCure> CURES = new ConcurrentHashMap<>();

public static Codec<EffectCure> CODEC = Codec.STRING.xmap(EffectCure::get, EffectCure::name);

/**
* {@return all registered cures}
* This collection can be kept around, and will update itself in response to changes to the map.
* See {@link ConcurrentHashMap#values()} for details.
*/
public static Collection<EffectCure> getActions() {
return Collections.unmodifiableCollection(CURES.values());
}

/**
* Gets or creates a new EffectCure for the given name.
*/
public static EffectCure get(String name) {
return CURES.computeIfAbsent(name, EffectCure::new);
}

/**
* {@return the name of this cure}
*/
public String name() {
return name;
}

@Override
public String toString() {
return "EffectCure[" + name + "]";
}

private final String name;

/**
* Use {@link #get(String)} to get or create an EffectCure
*/
private EffectCure(String name) {
this.name = name;
}
}
Loading

0 comments on commit 52cd634

Please sign in to comment.