Skip to content

Commit

Permalink
Backport the status effect changes (#387)
Browse files Browse the repository at this point in the history
  • Loading branch information
OroArmor authored Dec 2, 2024
1 parent 40c3d05 commit e6cbb6c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 47 deletions.
2 changes: 1 addition & 1 deletion build-logic/src/main/java/qsl/internal/Versions.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class Versions {
/**
* The QSL version
*/
public static final String QSL_VERSION = "6.2.0";
public static final String QSL_VERSION = "6.3.0";

/**
* The target Minecraft version.
Expand Down
1 change: 1 addition & 0 deletions library/entity/status_effect/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ qslModule {
moduleDependencies {
core {
api("qsl_base")
testmodOnly("resource_loader")
}
}
injectedInterface("net/minecraft/class_1309") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ private QuiltStatusEffectInternals() {

public static final String NAMESPACE = "quilt_status_effect";

public static final int MIXIN_PRIORITY = 500;

public static Identifier id(String path) {
return new Identifier(NAMESPACE, path);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,37 @@

package org.quiltmc.qsl.entity.effect.mixin;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.server.command.EffectCommand;

import org.quiltmc.qsl.entity.effect.api.StatusEffectRemovalReason;
import org.quiltmc.qsl.entity.effect.impl.QuiltStatusEffectInternals;

@Mixin(EffectCommand.class)
// See LivingEntityMixin
@Mixin(value = EffectCommand.class, priority = QuiltStatusEffectInternals.MIXIN_PRIORITY)
public abstract class EffectCommandMixin {
@Redirect(
@WrapOperation(
method = "executeClear(Lnet/minecraft/server/command/ServerCommandSource;Ljava/util/Collection;)I",
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;clearStatusEffects()Z")
)
private static boolean quilt$addRemovalReason(LivingEntity instance) {
private static boolean quilt$addRemovalReason(LivingEntity instance, Operation<Boolean> original) {
return instance.clearStatusEffects(StatusEffectRemovalReason.COMMAND_ALL) > 0;
}

@Redirect(
@WrapOperation(
method = "executeClear(Lnet/minecraft/server/command/ServerCommandSource;Ljava/util/Collection;Lnet/minecraft/registry/Holder;)I",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/LivingEntity;removeStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z"
)
)
private static boolean quilt$addRemovalReason(LivingEntity instance, StatusEffect type) {
private static boolean quilt$addRemovalReason(LivingEntity instance, StatusEffect type, Operation<Boolean> original) {
return instance.removeStatusEffect(type, StatusEffectRemovalReason.COMMAND_ONE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@

package org.quiltmc.qsl.entity.effect.mixin;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import com.google.common.collect.Iterators;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.entity.Entity;
Expand All @@ -40,8 +43,11 @@
import org.quiltmc.qsl.entity.effect.api.StatusEffectRemovalReason;
import org.quiltmc.qsl.entity.effect.api.StatusEffectUtils;
import org.quiltmc.qsl.entity.effect.impl.QuiltStatusEffectInternals;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(LivingEntity.class)
// We want to make sure that our wrap operations are put before other mods, so that we wrap the vanilla call and not a mod's call.
// This is because we do not call the vanilla method, so any mod adding something will not be called.
@Mixin(value = LivingEntity.class, priority = QuiltStatusEffectInternals.MIXIN_PRIORITY)
public abstract class LivingEntityMixin extends Entity implements QuiltLivingEntityStatusEffectExtensions {
@SuppressWarnings("ConstantConditions")
public LivingEntityMixin() {
Expand Down Expand Up @@ -116,44 +122,79 @@ public void onStatusEffectRemoved(@NotNull StatusEffectInstance effect, @NotNull
StatusEffectEvents.ON_APPLIED.invoker().onApplied((LivingEntity) (Object) this, effect, false);
}

@Redirect(
@WrapOperation(
method = "onStatusEffectRemoved",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/effect/StatusEffect;onRemoved(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/entity/attribute/AttributeContainer;I)V"
)
)
private void quilt$callOnRemovedWithReason(StatusEffect instance, LivingEntity entity, AttributeContainer attributes, int amplifier,
StatusEffectInstance effect) {
instance.onRemoved(entity, attributes, effect, this.quilt$lastRemovalReason);
StatusEffectEvents.ON_REMOVED.invoker().onRemoved(entity, effect, this.quilt$lastRemovalReason);
private void quilt$callOnRemovedWithReason(StatusEffect instance, LivingEntity entity, AttributeContainer attributes, int amplifier, Operation<Void> original, StatusEffectInstance effect) {
instance.onRemoved((LivingEntity) (Object) this, attributes, effect, this.quilt$lastRemovalReason);
StatusEffectEvents.ON_REMOVED.invoker().onRemoved((LivingEntity) (Object) this, effect, this.quilt$lastRemovalReason);
}

/**
* @author The Quilt Project
* @reason Adding removal reason
*/
@Overwrite
public boolean removeStatusEffect(StatusEffect type) {
return this.removeStatusEffect(type, StatusEffectRemovalReason.GENERIC_ONE);
@Inject(
method = "removeStatusEffect",
at = @At(
value = "HEAD"
),
cancellable = true
)
public void quilt$shouldRemoveEffect(StatusEffect effect, CallbackInfoReturnable<Boolean> cir) {
StatusEffectInstance instance = this.activeStatusEffects.get(effect);
if (instance != null) {
if (!StatusEffectUtils.shouldRemove((LivingEntity) (Object) this, instance, StatusEffectRemovalReason.GENERIC_ONE)) {
cir.setReturnValue(false);
}
}
}

@WrapOperation(
method = "removeStatusEffect",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/LivingEntity;onStatusEffectRemoved(Lnet/minecraft/entity/effect/StatusEffectInstance;)V"
)
)
public void quilt$addRemoveStatusEffectReason(LivingEntity instance, StatusEffectInstance effect, Operation<Void> original) {
this.quilt$lastRemovalReason = StatusEffectRemovalReason.GENERIC_ONE;
original.call(instance, effect);
this.quilt$lastRemovalReason = QuiltStatusEffectInternals.UNKNOWN_REASON;
}

/**
* @author The Quilt Project
* @reason Adding removal reason
*/
@Overwrite
public boolean clearStatusEffects() {
return this.clearStatusEffects(StatusEffectRemovalReason.GENERIC_ALL) > 0;
@WrapOperation(
method = "clearStatusEffects",
at = @At(
value = "INVOKE",
target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;"
)
)
private Iterator<StatusEffectInstance> quilt$filterStatusEffects(Collection<StatusEffectInstance> instance, Operation<Iterator<StatusEffectInstance>> original) {
return Iterators.filter(original.call(instance), effect -> StatusEffectUtils.shouldRemove(
(LivingEntity) (Object) this, effect, StatusEffectRemovalReason.GENERIC_ALL
));
}

@Redirect(method = "tickStatusEffects", at = @At(
@WrapOperation(method = "tickStatusEffects", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/LivingEntity;onStatusEffectRemoved(Lnet/minecraft/entity/effect/StatusEffectInstance;)V")
)
private void quilt$removeWithExpiredReason(LivingEntity instance, StatusEffectInstance effect) {
instance.onStatusEffectRemoved(effect, StatusEffectRemovalReason.EXPIRED);
StatusEffectEvents.ON_REMOVED.invoker().onRemoved(instance, effect, StatusEffectRemovalReason.EXPIRED);
private void quilt$removeWithExpiredReason(LivingEntity instance, StatusEffectInstance effect, Operation<Void> original) {
this.quilt$lastRemovalReason = StatusEffectRemovalReason.EXPIRED;
original.call(instance, effect);
}

@WrapOperation(
method = "onStatusEffectUpgraded",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/effect/StatusEffect;onRemoved(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/entity/attribute/AttributeContainer;I)V"
)
)
private void quilt$removeWithUpgradeApplyingReason(StatusEffect instance, LivingEntity entity, AttributeContainer attributes, int amplifier, Operation<Void> original, StatusEffectInstance statusEffectInstance) {
instance.onRemoved((LivingEntity) (Object) this, attributes, statusEffectInstance, StatusEffectRemovalReason.UPGRADE_REAPPLYING);
StatusEffectEvents.ON_REMOVED.invoker().onRemoved((LivingEntity) (Object) this, statusEffectInstance, StatusEffectRemovalReason.UPGRADE_REAPPLYING);
}

@SuppressWarnings("ConstantConditions")
Expand All @@ -168,14 +209,4 @@ public boolean clearStatusEffects() {
private void quilt$callOnAppliedEvent_upgradeReapplying(StatusEffectInstance effect, boolean reapplyEffect, Entity source, CallbackInfo ci) {
StatusEffectEvents.ON_APPLIED.invoker().onApplied((LivingEntity) (Object) this, effect, true);
}

@Redirect(method = "onStatusEffectUpgraded", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/effect/StatusEffect;onRemoved(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/entity/attribute/AttributeContainer;I)V")
)
private void quilt$removeWithUpgradeApplyingReason(StatusEffect instance, LivingEntity entity, AttributeContainer attributes, int amplifier,
StatusEffectInstance effect) {
instance.onRemoved(entity, attributes, effect, StatusEffectRemovalReason.UPGRADE_REAPPLYING);
StatusEffectEvents.ON_REMOVED.invoker().onRemoved(entity, effect, StatusEffectRemovalReason.UPGRADE_REAPPLYING);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@

package org.quiltmc.qsl.entity.effect.mixin;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import net.minecraft.entity.LivingEntity;
import net.minecraft.item.MilkBucketItem;

import org.quiltmc.qsl.entity.effect.api.StatusEffectRemovalReason;
import org.quiltmc.qsl.entity.effect.impl.QuiltStatusEffectInternals;

@Mixin(MilkBucketItem.class)
// See LivingEntityMixin
@Mixin(value = MilkBucketItem.class, priority = QuiltStatusEffectInternals.MIXIN_PRIORITY)
public abstract class MilkBucketItemMixin {
@Redirect(method = "finishUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;clearStatusEffects()Z"))
private boolean quilt$addRemovalReason(LivingEntity instance) {
@WrapOperation(method = "finishUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;clearStatusEffects()Z"))
private boolean quilt$addRemovalReason(LivingEntity instance, Operation<Boolean> original) {
return instance.clearStatusEffects(StatusEffectRemovalReason.DRANK_MILK) > 0;
}
}

0 comments on commit e6cbb6c

Please sign in to comment.