Skip to content

Commit

Permalink
LivingChangeTargetEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
IThundxr committed Mar 31, 2024
1 parent cecd25d commit af7816f
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.github.fabricators_of_create.porting_lib.mixin.common;

import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;

import org.spongepowered.asm.mixin.Mixin;
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.callback.CallbackInfoReturnable;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.datafixers.kinds.Const;
import com.mojang.datafixers.kinds.OptionalBox;
import com.mojang.datafixers.util.Unit;

import io.github.fabricators_of_create.porting_lib.entity.events.LivingEntityEvents.ChangeTarget.ChangeTargetEvent;
import io.github.fabricators_of_create.porting_lib.entity.events.LivingEntityEvents.ChangeTarget.ChangeTargetEvent.LivingTargetType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.behavior.StartAttacking;
import net.minecraft.world.entity.ai.behavior.declarative.MemoryAccessor;

@Mixin(StartAttacking.class)
public class StartAttackingMixin {
@Unique private static ChangeTargetEvent port_lib$changeTargetEvent;

@Inject(
method = "method_47123(Ljava/util/function/Predicate;Ljava/util/function/Function;Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Mob;J)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;set(Ljava/lang/Object;)V"
),
cancellable = true
)
private static <E extends Mob> void port_lib$onChangeTarget(Predicate<E> predicate, Function<E, Optional<? extends LivingEntity>> function, MemoryAccessor<Const.Mu<Unit>, LivingEntity> memoryAccessor, MemoryAccessor<OptionalBox.Mu, Long> memoryAccessor2, ServerLevel serverLevel, Mob mob, long l, CallbackInfoReturnable<Boolean> cir, @Local LivingEntity livingEntity) {
port_lib$changeTargetEvent = new ChangeTargetEvent(mob, livingEntity, LivingTargetType.BEHAVIOR_TARGET);
port_lib$changeTargetEvent.sendEvent();

if (port_lib$changeTargetEvent.isCanceled())
cir.setReturnValue(false);
}

@WrapOperation(
method = "method_47123(Ljava/util/function/Predicate;Ljava/util/function/Function;Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Mob;J)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/ai/behavior/declarative/MemoryAccessor;set(Ljava/lang/Object;)V"
)
)
private static void port_lib$wrapToChangeTarget(MemoryAccessor<Const.Mu<Unit>, LivingEntity> instance, Object object, Operation<Void> original) {
original.call(instance, port_lib$changeTargetEvent.getNewTarget());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"common.SignalGetterMixin",
"common.SnowGolemMixin",
"common.SpawnerBlockMixin",
"common.StartAttackingMixin",
"common.StemBlockMixin",
"common.StructureProcessorMixin",
"common.StructureTemplateMixin",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import io.github.fabricators_of_create.porting_lib.core.event.BaseEvent;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.world.damagesource.DamageSource;
Expand Down Expand Up @@ -132,6 +131,14 @@ public abstract class LivingEntityEvents extends EntityEvents {
return originalMultiplier;
});

public static final Event<ChangeTarget> CHANGE_TARGET = EventFactory.createArrayBacked(ChangeTarget.class, callbacks -> (event) -> {
for (ChangeTarget e : callbacks) {
e.onChangeTarget(event);
if (event.isCanceled())
return;
}
});

private final LivingEntity livingEntity;

public LivingEntityEvents(LivingEntity entity) {
Expand Down Expand Up @@ -355,4 +362,34 @@ public interface Visibility {
public interface NewVisibility {
void getEntityVisibilityMultiplier(LivingVisibilityEvent event);
}

@FunctionalInterface
public interface ChangeTarget {
void onChangeTarget(ChangeTargetEvent event);

final class ChangeTargetEvent extends EntityEvents {
private final LivingTargetType targetType;
private final LivingEntity originalTarget;
private LivingEntity newTarget;

public ChangeTargetEvent(LivingEntity entity, LivingEntity originalTarget, LivingTargetType targetType) {
super(entity);
this.originalTarget = originalTarget;
this.newTarget = originalTarget;
this.targetType = targetType;
}

@Override
public void sendEvent() {
CHANGE_TARGET.invoker().onChangeTarget(this);
}

public LivingEntity getNewTarget() { return newTarget; }
public void setNewTarget(LivingEntity newTarget) { this.newTarget = newTarget; }
public LivingTargetType getTargetType() { return targetType; }
public LivingEntity getOriginalTarget() { return originalTarget; }

public enum LivingTargetType { MOB_TARGET, BEHAVIOR_TARGET }
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
package io.github.fabricators_of_create.porting_lib.entity.mixin.common;

import io.github.fabricators_of_create.porting_lib.entity.events.MobEntitySetTargetCallback;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;

import org.spongepowered.asm.mixin.Mixin;
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.callback.CallbackInfo;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;

import io.github.fabricators_of_create.porting_lib.entity.events.LivingEntityEvents.ChangeTarget.ChangeTargetEvent;
import io.github.fabricators_of_create.porting_lib.entity.events.LivingEntityEvents.ChangeTarget.ChangeTargetEvent.LivingTargetType;
import io.github.fabricators_of_create.porting_lib.entity.events.MobEntitySetTargetCallback;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;

@Mixin(Mob.class)
public abstract class MobMixin {
@Unique private ChangeTargetEvent port_lib$changeTargetEvent;

@Inject(method = "setTarget", at = @At("HEAD"), cancellable = true)
private void port_lib$onChangeTarget(LivingEntity target, CallbackInfo ci) {
port_lib$changeTargetEvent = new ChangeTargetEvent((Mob) (Object) this, target, LivingTargetType.MOB_TARGET);
port_lib$changeTargetEvent.sendEvent();
if (port_lib$changeTargetEvent.isCanceled())
ci.cancel();
}

@WrapOperation(method = "setTarget", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/Mob;target:Lnet/minecraft/world/entity/LivingEntity;"))
private void port_lib$wrapSetTarget(Mob instance, LivingEntity value, Operation<Void> original) {
original.call(instance, port_lib$changeTargetEvent.getNewTarget());
}

@Inject(method = "setTarget", at = @At("TAIL"))
private void port_lib$setTarget(LivingEntity target, CallbackInfo ci) {
MobEntitySetTargetCallback.EVENT.invoker().onMobEntitySetTarget((Mob) (Object) this, target);
Expand Down

0 comments on commit af7816f

Please sign in to comment.