TheWildBackport/common/src/main/java/com/cursedcauldron/wildbackport/core/mixin/common/MobEffectMixin.java
2022-08-25 17:53:18 -04:00

89 lines
4.2 KiB
Java

package com.cursedcauldron.wildbackport.core.mixin.common;
import com.cursedcauldron.wildbackport.WildBackport;
import com.cursedcauldron.wildbackport.common.effects.EffectFactor;
import com.cursedcauldron.wildbackport.common.effects.FactorCalculationData;
import com.mojang.serialization.Dynamic;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
import java.util.function.Supplier;
@Mixin(MobEffect.class)
public class MobEffectMixin implements EffectFactor {
private Supplier<FactorCalculationData> factorCalculationData = () -> null;
@Override
public MobEffect setFactorCalculationData(Supplier<FactorCalculationData> data) {
this.factorCalculationData = data;
return MobEffect.class.cast(this);
}
@Override
public Supplier<FactorCalculationData> getFactorCalculationData() {
return this.factorCalculationData;
}
@Mixin(MobEffectInstance.class)
public static class MobEffectInstanceMixin implements EffectFactor.Instance {
@Shadow @Final private MobEffect effect;
@Shadow private int duration;
private Optional<FactorCalculationData> factorCalculationData;
@Inject(method = "<init>(Lnet/minecraft/world/effect/MobEffect;IIZZZLnet/minecraft/world/effect/MobEffectInstance;)V", at = @At("TAIL"))
private void wb$create(MobEffect effect, int duration, int amplifier, boolean ambient, boolean showParticles, boolean showIcon, MobEffectInstance hiddenEffect, CallbackInfo ci) {
this.setFactorCalculationData(EffectFactor.create(effect));
}
@Inject(method = "<init>(Lnet/minecraft/world/effect/MobEffectInstance;)V", at = @At("TAIL"))
private void wb$create(MobEffectInstance instance, CallbackInfo ci) {
this.setFactorCalculationData(EffectFactor.create(this.effect));
}
@Override
public void setFactorCalculationData(Optional<FactorCalculationData> data) {
this.factorCalculationData = data;
}
@Override
public Optional<FactorCalculationData> getFactorCalculationData() {
return this.factorCalculationData;
}
@Inject(method = "update", at = @At("HEAD"), cancellable = true)
private void wb$update(MobEffectInstance instance, CallbackInfoReturnable<Boolean> cir) {
int i = this.duration;
if (i != this.duration) {
this.factorCalculationData.ifPresent(data -> data.effectChangedTimestamp += this.duration - i);
cir.setReturnValue(true);
}
}
@Inject(method = "tick", at = @At("HEAD"))
private void wb$tick(LivingEntity entity, Runnable runnable, CallbackInfoReturnable<Boolean> cir) {
this.factorCalculationData.ifPresent(data -> data.update(MobEffectInstance.class.cast(this)));
}
@Inject(method = "writeDetailsTo", at = @At("TAIL"))
private void wb$write(CompoundTag tag, CallbackInfo ci) {
this.factorCalculationData.flatMap(instance -> FactorCalculationData.CODEC.encodeStart(NbtOps.INSTANCE, instance).resultOrPartial(WildBackport.LOGGER::error)).ifPresent(data -> tag.put("FactorCalculationData", data));
}
@Inject(method = "loadSpecifiedEffect", at = @At("TAIL"))
private static void wb$load(MobEffect effect, CompoundTag tag, CallbackInfoReturnable<MobEffectInstance> cir) {
Optional<FactorCalculationData> data = tag.contains("FactorCalculationData", 10) ? FactorCalculationData.CODEC.parse(new Dynamic<>(NbtOps.INSTANCE, tag.getCompound("FactorCalculationData"))).resultOrPartial(WildBackport.LOGGER::error) : Optional.empty();
EffectFactor.Instance.of(cir.getReturnValue()).setFactorCalculationData(data);
}
}
}