From 83e74616b3aa4c6e3542c82739206351fb0a7e09 Mon Sep 17 00:00:00 2001
From: Vendo
Date: Sat, 18 May 2024 21:37:44 +1000
Subject: [PATCH] Added EntityTotemActivateEvent (#48)
* Added EntityTotemActivateEvent
* Made the mixin not dumb and cleaned up.
* Check isClient before invoking event
* Return early for the isClient check
* Fix the isClient check
---
.../entity/EntityActivateTotemEvent.java | 37 +++++++++++++++++++
.../mixin/entity/LivingEntityMixin.java | 17 +++++++++
2 files changed, 54 insertions(+)
create mode 100644 src/main/java/xyz/nucleoid/stimuli/event/entity/EntityActivateTotemEvent.java
diff --git a/src/main/java/xyz/nucleoid/stimuli/event/entity/EntityActivateTotemEvent.java b/src/main/java/xyz/nucleoid/stimuli/event/entity/EntityActivateTotemEvent.java
new file mode 100644
index 0000000..810f288
--- /dev/null
+++ b/src/main/java/xyz/nucleoid/stimuli/event/entity/EntityActivateTotemEvent.java
@@ -0,0 +1,37 @@
+package xyz.nucleoid.stimuli.event.entity;
+
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.damage.DamageSource;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ActionResult;
+import xyz.nucleoid.stimuli.event.StimulusEvent;
+
+/**
+ * Called when a {@link LivingEntity} activates a totem of undying.
+ *
+ * Upon return:
+ *
+ * - {@link ActionResult#SUCCESS} cancels further processing and activates the totem.
+ *
- {@link ActionResult#FAIL} cancels further processing and does not activate the totem.
+ *
- {@link ActionResult#PASS} moves on to the next listener.
+ *
+ *
+ */
+public interface EntityActivateTotemEvent {
+
+ StimulusEvent EVENT = StimulusEvent.create(EntityActivateTotemEvent.class, ctx -> (entity, source, itemStack) -> {
+ try {
+ for (var listener : ctx.getListeners()) {
+ var result = listener.onTotemActivate(entity, source, itemStack);
+ if (result != ActionResult.PASS) {
+ return result;
+ }
+ }
+ } catch (Throwable t) {
+ ctx.handleException(t);
+ }
+ return ActionResult.PASS;
+ });
+
+ ActionResult onTotemActivate(LivingEntity entity, DamageSource source, ItemStack itemStack);
+}
diff --git a/src/main/java/xyz/nucleoid/stimuli/mixin/entity/LivingEntityMixin.java b/src/main/java/xyz/nucleoid/stimuli/mixin/entity/LivingEntityMixin.java
index 42bbec9..ab96a41 100644
--- a/src/main/java/xyz/nucleoid/stimuli/mixin/entity/LivingEntityMixin.java
+++ b/src/main/java/xyz/nucleoid/stimuli/mixin/entity/LivingEntityMixin.java
@@ -2,6 +2,7 @@
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
@@ -17,6 +18,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import xyz.nucleoid.stimuli.Stimuli;
+import xyz.nucleoid.stimuli.event.entity.EntityActivateTotemEvent;
import xyz.nucleoid.stimuli.event.entity.EntityDamageEvent;
import xyz.nucleoid.stimuli.event.entity.EntityDeathEvent;
import xyz.nucleoid.stimuli.event.entity.EntityDropItemsEvent;
@@ -81,4 +83,19 @@ private void modifyDroppedLoot(LootTable instance, LootContextParameterSet param
}
}
}
+
+ @Inject(method = "tryUseTotem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;decrement(I)V"), cancellable = true)
+ private void tryUseTotem(DamageSource source, CallbackInfoReturnable cir, @Local(ordinal = 1) ItemStack itemStack) {
+ if (this.getWorld().isClient) {
+ return;
+ }
+
+ var entity = (LivingEntity) (Object) this;
+ try (var invokers = Stimuli.select().forEntity(entity)) {
+ var result = invokers.get(EntityActivateTotemEvent.EVENT).onTotemActivate(entity, source, itemStack);
+ if (result == ActionResult.FAIL) {
+ cir.setReturnValue(false);
+ }
+ }
+ }
}