#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using TagFighter.Effects.ResourceLocationAccessors.ContextRegisters;
using TagFighter.Effects.Steps;
using TagFighter.Resources;
using UnityEngine;
namespace TagFighter
{
public struct EffectOrigin
{
public Transform Transform;
public EffectOrigin(Transform transform) {
Transform = transform;
}
}
public struct EffectTarget
{
public Transform Transform;
public EffectTarget(Transform transform) {
Transform = transform;
}
}
}
namespace TagFighter.Effects
{
public class ReleaseMultiplier
{
public Type? MatchingAoe { get; set; }
public float MatchingAoeReleaseMultiplier { get; set; } = 1f;
public float NonMatchingAoeReleaseMultiplier { get; set; } = 1f;
}
public record RegistryKey
{
public Type ContextRegisterType;
public Type ResourceType;
public RegistryKey(Type contextRegisterType, Type resourceType) {
ContextRegisterType = contextRegisterType;
ResourceType = resourceType;
}
}
public class EffectContext
{
Dictionary<RegistryKey, IUnit> _resourceRegistry = new();
public EffectOrigin Caster { get; set; }
public EffectTarget EffectLocation { get; set; }
public IAreaOfEffect AreaOfEffect;
public List<IDelayedEffect> EffectsToTrigger { get; set; } = new();
public List<OutputStep<bool>> EffectStepsToTrigger { get; set; } = new();
public IEffectSystem EffectSystem { get; private set; }
public ReleaseMultiplier ReleaseMultiplier { get; set; }
public EffectContext(EffectOrigin caster, EffectTarget effectLocation) {
EffectSystem = SystemsHandler.EffectSystem;
ReleaseMultiplier = new();
Caster = caster;
EffectLocation = effectLocation;
AreaOfEffect = new SingleTarget();
}
public Unit<TUnit> GetResource<TResource, TUnit, TContextRegister>()
where TResource : Resource<TUnit>
where TUnit : IUnitType
where TContextRegister : IContextRegister {
var key = new RegistryKey(typeof(TContextRegister), typeof(TResource));
var value = (Unit<TUnit>)_resourceRegistry.GetValueOrDefault(key, (Unit<TUnit>)0);
Debug.Log($"{nameof(GetResource)} ({typeof(TResource).Name},{typeof(TContextRegister).Name}) = {value}");
return value;
}
public Unit<TUnit> SetResource<TResource, TUnit, TContextRegister>(Unit<TUnit> value)
where TResource : Resource<TUnit>
where TUnit : IUnitType
where TContextRegister : IContextRegister {
var key = new RegistryKey(typeof(TContextRegister), typeof(TResource));
var newValue = (Unit<TUnit>)(_resourceRegistry[key] = value);
Debug.Log($"{nameof(SetResource)} ({typeof(TResource).Name},{typeof(TContextRegister).Name}) = {newValue}");
return newValue;
}
public IEnumerable<(Type, IUnit)> GetAllResourcesInRegister<TContextRegister>() where TContextRegister : IContextRegister {
return _resourceRegistry.Where(x => x.Key.ContextRegisterType == typeof(TContextRegister)).Select(x => (x.Key.ResourceType, x.Value));
}
public IEnumerable<Transform> GetAffectedUnits() {
var affectedUnits = AreaOfEffect.GetAffectedUnits(Caster, EffectLocation);
return affectedUnits;
}
void ResetEffects() {
EffectsToTrigger.Clear();
EffectStepsToTrigger.Clear();
}
public void Reset() {
ResetEffects();
}
}
}