using System;
using System.Collections.Generic;
using System.Linq;
using CareBoo.Serially;
using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;
using TagFighter.Resources;
using UnityEngine;
namespace TagFighter.Effects
{
public interface IDelayedEffect
{
void DelayedAction(EffectInput data);
}
public interface IImmediateEffect
{
void ImmediateAction(EffectContext context, IEffect effect);
}
public interface IEffectMode
{
void Apply(EffectContext context);
void Effect(EffectContext context, IEffect effect);
}
[ProvideSourceInfo]
[Serializable]
public class DelayedEffect : IImmediateEffect, IDelayedEffect
{
IEffect _effect;
public void DelayedAction(EffectInput data) {
_effect.Apply(data);
var directionVector = (data.Context.EffectLocation.Transform.position - data.Context.Caster.Transform.position).normalized;
directionVector.y = 0;
var direction = Quaternion.LookRotation(directionVector, Vector3.up);
var appliedResource = data.Context.GetAllResourcesInRegister<Added>();
data.Context.EffectSystem.ApplyTagsEffect(appliedResource, data.Context.Caster, direction, data.Context.AreaOfEffect);
}
public void ImmediateAction(EffectContext context, IEffect effect) {
if (effect != null) {
_effect = effect;
context.EffectsToTrigger.Add(this);
}
}
}
[ProvideSourceInfo]
[Serializable]
public class ImmediateEffect : IImmediateEffect
{
[SerializeReference, ShowSerializeReference]
AoeShapes.IAoeShape _areaOfEffect;
public void ImmediateAction(EffectContext context, IEffect effect) {
if (effect != null) {
var directionVector = (context.EffectLocation.Transform.position - context.Caster.Transform.position).normalized;
directionVector.y = 0;
var direction = Quaternion.LookRotation(directionVector, Vector3.up);
EffectInput data = new(context, Enumerable.Empty<Transform>(), StatModifierAccessor.Permanent);
var areaOfEffect = _areaOfEffect.AreaOfEffect(data);
data.Affected = areaOfEffect.GetAffectedUnits(context.Caster, context.EffectLocation);
effect.Apply(data);
var appliedResource = context.GetAllResourcesInRegister<Added>();
context.EffectSystem.ApplyTagsEffect(appliedResource, context.Caster, direction, areaOfEffect);
}
}
}
[ProvideSourceInfo]
[Serializable]
public class ImmediateWeave : IImmediateEffect
{
public void ImmediateAction(EffectContext context, IEffect effect) {
EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);
if (effect != null) {
effect.Apply(data);
data.Affected = context.GetAffectedUnits();
}
Materialize(data);
}
void Materialize(EffectInput data) {
foreach (var effect in data.Context.EffectsToTrigger) {
effect.DelayedAction(data);
}
data.Context.EffectsToTrigger.Clear();
}
}
[ProvideSourceInfo]
[Serializable]
public class PeriodicWeave : IImmediateEffect
{
[SerializeReference, ShowSerializeReference]
public AoeShapes.IAoeShape AreaOfEffect;
[SerializeReference, ShowSerializeReference]
public Triggers.ITrigger ApplyTrigger;
[SerializeReference, ShowSerializeReference]
public Triggers.ITrigger EndTrigger;
public bool IsPermanent;
public void ImmediateAction(EffectContext context, IEffect effect) {
EffectInput data = new(context, context.GetAffectedUnits(), StatModifierAccessor.Permanent);
if (effect != null) {
effect.Apply(data);
data.Affected = context.GetAffectedUnits();
}
Materialize(data);
}
void Materialize(EffectInput data) {
var areaOfEffect = AreaOfEffect.AreaOfEffect(data);
List<IDelayedEffect> effectsToTrigger = new(data.Context.EffectsToTrigger);
data.Context.EffectsToTrigger.Clear();
var origin = data.Context.Caster;
foreach (var affectedPawn in data.Affected) {
var condition = IsPermanent ? affectedPawn.gameObject.AddComponent<PawnCondition>() : affectedPawn.gameObject.AddComponent<TransientPawnCondition>();
condition.EndTrigger = EndTrigger?.ShallowCopy();
condition.ApplyTrigger = ApplyTrigger?.ShallowCopy();
condition.Origin = origin;
condition.Context = new EffectContext(new(affectedPawn), new(affectedPawn)) {
AreaOfEffect = areaOfEffect,
EffectsToTrigger = effectsToTrigger
};
condition.Apply();
}
}
}
}