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 = JexGasObjectPool.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.EntityId} 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);
}
}
}