using System; using System.Collections.Generic; using System.Linq; using System.Text; using Cielonos.MainGame.Characters; using SLSUtilities.General; using SLSUtilities.FunctionalAnimation; using UnityEngine; namespace Cielonos.MainGame { public static class Attack { public enum Type { Energy = 1, Kinetics = 2, Explosion = 3, Magic = 4, Pure = 5, Blank = 6, // 代表不具有特定攻击类型的伤害,例如持续伤害、反伤等 } public static string AttackTypeToString(this Type type) { return type switch { Type.Energy => "Energy", Type.Kinetics => "Kinetics", Type.Explosion => "Explosion", Type.Magic => "Magic", Type.Pure => "Pure", Type.Blank => "Blank", _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) }; } public class Value : ICloneable { public bool isCritical; public float damage; public Type type; public Breakthrough.Type breakthroughType; public DisruptionType disruptionType; public List tags; public float damageMultiplier = 1f; public float additionalFlatDamage = 0f; public Value(bool isCritical, float damage, Type type, DisruptionType disruptionType = DisruptionType.None, Breakthrough.Type breakthroughType = Breakthrough.Type.None, List tags = null) { this.isCritical = isCritical; this.damage = damage; this.type = type; this.disruptionType = disruptionType; this.breakthroughType = breakthroughType; this.tags = tags != null ? new List(tags) : new List(); } public Value Clone() { Value cloned = new Value(isCritical, damage, type, disruptionType, breakthroughType, tags); cloned.damageMultiplier = this.damageMultiplier; cloned.additionalFlatDamage = this.additionalFlatDamage; return cloned; } } /// /// 攻击上下文:在伤害结算前传递,允许订阅者修改攻击参数和前置决策标记。 /// 用于 onStartAttack / onBeforeGetAttacked 阶段。 /// public class Context { public CharacterBase attacker; public CharacterBase target; public Vector3 hitPosition; public string spamGroupID; /// /// 可修改的攻击值,订阅者可在结算前调整 damageMultiplier、additionalFlatDamage 等。 /// public Value value; /// /// 前置否决标记:设为 true 则跳过伤害结算,攻击完全无效化。 /// public bool isImmune; /// /// 前置否决标记:设为 true 则强制中断攻击流程。 /// public bool isForcedInterrupt; public Context(CharacterBase attacker, CharacterBase target, string spamGroupMainPart, Vector3 hitPosition = default) { this.attacker = attacker; this.target = target; StringBuilder fullIDBuilder = new StringBuilder(); fullIDBuilder.Append(attacker is null ? "Null" : attacker.GetInstanceID().ToString()); fullIDBuilder.Append("_"); fullIDBuilder.Append(spamGroupMainPart); fullIDBuilder.Append("_"); fullIDBuilder.Append(target is null ? "Null" : target.GetInstanceID().ToString()); this.spamGroupID = fullIDBuilder.ToString(); this.hitPosition = hitPosition; } } /// /// 攻击结果:伤害结算完成后的数据载体,包含结算结果和对原始上下文的引用。 /// 用于 onFinishAttack / onAfterGetAttacked 阶段。 /// public class Result { /// /// 引用原始攻击上下文,包含攻击参数和前置决策。 /// public Context context; public bool isBlocked; public bool isDodged; public bool isReflected; public bool isMissed; public bool isEvaded; public bool causedDeath; public float shieldBlockedDamage; public float finalDamage; // 便捷访问属性,代理到 Context public CharacterBase attacker => context.attacker; public CharacterBase target => context.target; public Vector3 hitPosition => context.hitPosition; public string spamGroupID => context.spamGroupID; public Value value { get => context.value; set => context.value = value; } /// /// 从已有上下文构建结果。用于标准攻击流程:Context 阶段完成后包装为 Result。 /// public Result(Context context) { this.context = context; } /// /// 直接从参数构建结果,用于Buff直接附伤等流程。会自动构建 Context 并关联 Value。 /// public Result(Context context, Value value) { this.context = context; this.value = value; } } } public static class Breakthrough { public enum Type { None = 0, Weak = 10, Medium = 20, Heavy = 30, Disruption = 40, Forced = 50, Unstoppable = 100 // 不可用于攻击,只能用于防御状态,表示无法被打断 } public static readonly List Types = new List() { Type.None, Type.Weak, Type.Medium, Type.Heavy, Type.Disruption, Type.Forced, Type.Unstoppable }; public static List GetLowerTypes(Type type) { return Types.Where(t => t < type).ToList(); } public static List GetEqualOrLowerTypes(Type type) { return Types.Where(t => t <= type).ToList(); } public static List GetHigherTypes(Type type) { return Types.Where(t => t > type).ToList(); } public static List GetEqualOrHigherTypes(Type type) { return Types.Where(t => t >= type).ToList(); } } }