using System; using GAS.General; using Sirenix.OdinInspector; using UnityEngine; namespace GAS.Runtime { /// /// 授予能力的激活策略 /// public enum GrantedAbilityActivationPolicy { /// /// 不激活, 等待用户调用ASC激活 /// [LabelText("None - 不激活, 等待用户调用ASC激活", SdfIconType.Joystick)] None, /// /// 能力添加时激活(GE添加时激活) /// [LabelText("WhenAdded - 能力添加时激活(GE添加时激活)", SdfIconType.LightningChargeFill)] WhenAdded, /// /// 同步GE激活时激活 /// [LabelText("SyncWithEffect - 同步GE激活时激活", SdfIconType.Robot)] SyncWithEffect, } /// /// 授予能力的取消激活策略 /// public enum GrantedAbilityDeactivationPolicy { /// /// 无相关取消激活逻辑, 需要用户调用ASC取消激活 /// [LabelText("None - 无相关取消激活逻辑, 需要用户调用ASC取消激活", SdfIconType.Joystick)] None, /// /// 同步GE,GE失活时取消激活 /// [LabelText("SyncWithEffect - 同步GE,GE失活时取消激活", SdfIconType.Robot)] SyncWithEffect, } /// /// 授予能力的移除策略 /// public enum GrantedAbilityRemovePolicy { /// /// 不移除 /// [LabelText("None - 不移除", SdfIconType.Joystick)] None, /// /// 同步GE,GE移除时移除 /// [LabelText("SyncWithEffect - 同步GE,GE移除时移除", SdfIconType.Robot)] SyncWithEffect, /// /// 能力结束时自己移除 /// [LabelText("WhenEnd - 能力结束时自己移除", SdfIconType.LightningChargeFill)] WhenEnd, /// /// 能力取消时自己移除 /// [LabelText("WhenCancel - 能力取消时自己移除", SdfIconType.LightningChargeFill)] WhenCancel, /// /// 能力结束或取消时自己移除 /// [LabelText("WhenCancelOrEnd - 能力结束或取消时自己移除", SdfIconType.LightningChargeFill)] WhenCancelOrEnd, } [Serializable] public struct GrantedAbilityConfig { private const int LABEL_WIDTH = 50; [LabelWidth(LABEL_WIDTH)] [LabelText(GASTextDefine.LABEL_GRANT_ABILITY)] [AssetSelector] public AbilityAsset AbilityAsset; [LabelWidth(LABEL_WIDTH)] [LabelText(GASTextDefine.LABEL_GRANT_ABILITY_LEVEL)] public int AbilityLevel; [LabelWidth(LABEL_WIDTH)] [LabelText(GASTextDefine.LABEL_GRANT_ABILITY_ACTIVATION_POLICY)] [Tooltip(GASTextDefine.TIP_GRANT_ABILITY_ACTIVATION_POLICY)] public GrantedAbilityActivationPolicy ActivationPolicy; [LabelWidth(LABEL_WIDTH)] [LabelText(GASTextDefine.LABEL_GRANT_ABILITY_DEACTIVATION_POLICY)] [Tooltip(GASTextDefine.TIP_GRANT_ABILITY_DEACTIVATION_POLICY)] public GrantedAbilityDeactivationPolicy DeactivationPolicy; [LabelWidth(LABEL_WIDTH)] [LabelText(GASTextDefine.LABEL_GRANT_ABILITY_REMOVE_POLICY)] [Tooltip(GASTextDefine.TIP_GRANT_ABILITY_REMOVE_POLICY)] public GrantedAbilityRemovePolicy RemovePolicy; } public class GrantedAbilityFromEffect { public readonly AbstractAbility Ability; public readonly int AbilityLevel; public readonly GrantedAbilityActivationPolicy ActivationPolicy; public readonly GrantedAbilityDeactivationPolicy DeactivationPolicy; public readonly GrantedAbilityRemovePolicy RemovePolicy; public GrantedAbilityFromEffect(GrantedAbilityConfig config) { Ability = Activator.CreateInstance(config.AbilityAsset.AbilityType(), args: config.AbilityAsset) as AbstractAbility; AbilityLevel = config.AbilityLevel; ActivationPolicy = config.ActivationPolicy; DeactivationPolicy = config.DeactivationPolicy; RemovePolicy = config.RemovePolicy; } public GrantedAbilityFromEffect( AbstractAbility ability, int abilityLevel, GrantedAbilityActivationPolicy activationPolicy, GrantedAbilityDeactivationPolicy deactivationPolicy, GrantedAbilityRemovePolicy removePolicy) { Ability = ability; AbilityLevel = abilityLevel; ActivationPolicy = activationPolicy; DeactivationPolicy = deactivationPolicy; RemovePolicy = removePolicy; } public GrantedAbilitySpecFromEffect CreateSpec(GameplayEffectSpec sourceEffectSpec) { var grantedAbilitySpecFromEffect = ObjectPool.Instance.Fetch(); grantedAbilitySpecFromEffect.Awake(this, sourceEffectSpec); return grantedAbilitySpecFromEffect; } } public class GrantedAbilitySpecFromEffect : IEntity { public ulong InstanceId { get; private set; } public GrantedAbilityFromEffect GrantedAbility { get; private set; } public GameplayEffectSpec SourceEffectSpec { get; private set; } public AbilitySystemComponent Owner { get; private set; } public string AbilityName { get; private set; } public int AbilityLevel => GrantedAbility.AbilityLevel; public GrantedAbilityActivationPolicy ActivationPolicy => GrantedAbility.ActivationPolicy; public GrantedAbilityDeactivationPolicy DeactivationPolicy => GrantedAbility.DeactivationPolicy; public GrantedAbilityRemovePolicy RemovePolicy => GrantedAbility.RemovePolicy; public AbilitySpec AbilitySpec => Owner.AbilityContainer.AbilitySpecs()[AbilityName]; public void Awake(GrantedAbilityFromEffect grantedAbility, GameplayEffectSpec sourceEffectSpec) { InstanceId = IdGenerator.Next; GrantedAbility = grantedAbility; SourceEffectSpec = sourceEffectSpec; AbilityName = GrantedAbility.Ability.Name; Owner = SourceEffectSpec.Owner; if (Owner.AbilityContainer.HasAbility(AbilityName)) { Debug.LogError($"GrantedAbilitySpecFromEffect: {Owner.name} already has ability {AbilityName}"); } Owner.GrantAbility(GrantedAbility.Ability); AbilitySpec.SetLevel(AbilityLevel); // 是否添加时激活 if (ActivationPolicy == GrantedAbilityActivationPolicy.WhenAdded) { Owner.TryActivateAbility(AbilityName, sourceEffectSpec); } switch (RemovePolicy) { case GrantedAbilityRemovePolicy.WhenEnd: AbilitySpec.RegisterEndAbility(RemoveSelf); break; case GrantedAbilityRemovePolicy.WhenCancel: AbilitySpec.RegisterCancelAbility(RemoveSelf); break; case GrantedAbilityRemovePolicy.WhenCancelOrEnd: AbilitySpec.RegisterEndAbility(RemoveSelf); AbilitySpec.RegisterCancelAbility(RemoveSelf); break; } } public void Release() { InstanceId = default; GrantedAbility = default; Owner = default; AbilityName = default; SourceEffectSpec = default; } private void RemoveSelf() { Owner.RemoveAbility(AbilityName); } } }