using System.Text;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Entity
{
///
/// 与 不同,构造技能时,建议继承此类再构造
///
public class Skill : BaseEntity, IActiveEnable
{
///
/// 此技能所属的角色
///
public Character? Character { get; set; } = null;
///
/// 技能描述
///
public virtual string Description { get; set; } = "";
///
/// 技能的通用描述
///
public virtual string GeneralDescription { get; set; } = "";
///
/// 技能等级,等于 0 时可以称之为尚未学习
///
public int Level
{
get
{
return Math.Max(0, _Level);
}
set
{
int max = SkillSet.GetSkillMaxLevel(SkillType);
_Level = Math.Min(Math.Max(0, value), max);
OnLevelUp();
}
}
///
/// 技能类型 [ 此项为最高优先级 ]
///
[InitRequired]
public SkillType SkillType { get; set; }
///
/// 是否是主动技能 [ 此项为高优先级 ]
///
[InitRequired]
public bool IsActive => SkillType != SkillType.Passive;
///
/// 是否可用 [ 此项为高优先级 ]
///
public bool Enable { get; set; } = true;
///
/// 效果持续生效中 [ 此项为高优先级 ] [ 此项设置为true后不允许再次释放,防止重复释放 ]
///
public bool IsInEffect { get; set; } = false;
///
/// 是否是爆发技 [ 此项为高优先级 ]
///
[InitRequired]
public bool IsSuperSkill => SkillType == SkillType.SuperSkill;
///
/// 是否属于魔法 [ 必须为 true ],反之为战技
///
[InitRequired]
public bool IsMagic => SkillType == SkillType.Magic;
///
/// 实际魔法消耗 [ 魔法 ]
///
public double RealMPCost => Math.Max(0, MPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * 0.00125)));
///
/// 魔法消耗 [ 魔法 ]
///
[InitOptional]
public virtual double MPCost { get; set; } = 0;
///
/// 实际吟唱时间 [ 魔法 ]
///
public double RealCastTime => Math.Max(0, CastTime * (1 - Calculation.PercentageCheck(Character?.AccelerationCoefficient ?? 0)));
///
/// 吟唱时间 [ 魔法 ]
///
[InitOptional]
public virtual double CastTime { get; set; } = 0;
///
/// 实际能量消耗 [ 战技 ]
///
public double RealEPCost => IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * 0.00075)));
///
/// 能量消耗 [ 战技 ]
///
[InitOptional]
public virtual double EPCost { get; set; } = 0;
///
/// 实际冷却时间
///
public double RealCD => Math.Max(0, CD * (1 - Character?.CDR ?? 0));
///
/// 冷却时间
///
[InitRequired]
public virtual double CD { get; set; } = 0;
///
/// 剩余冷却时间 [ 建议配合 属性使用 ]
///
public double CurrentCD { get; set; } = 0;
///
/// 硬直时间
///
[InitRequired]
public virtual double HardnessTime { get; set; } = 0;
///
/// 效果列表
///
public HashSet Effects { get; } = [];
///
/// 其他参数
///
public Dictionary OtherArgs { get; } = [];
///
/// 游戏中的行动顺序表实例,在技能效果被触发时,此实例会获得赋值,使用时需要判断其是否存在
///
public ActionQueue? ActionQueue { get; set; } = null;
///
/// 技能是否属于某个物品
///
public Item? Item { get; set; } = null;
///
/// 继承此类实现时,调用基类的构造函数
///
///
///
protected Skill(SkillType type, Character? character = null)
{
SkillType = type;
Character = character;
}
///
/// 用于构造 JSON
///
internal Skill() { }
///
/// 触发技能升级
///
public void OnLevelUp()
{
if (!IsActive && Level > 0)
{
foreach (Effect e in AddInactiveEffectToCharacter())
{
e.ActionQueue = ActionQueue;
if (Character != null && !Character.Effects.Contains(e))
{
Character.Effects.Add(e);
e.OnEffectGained(Character);
}
}
}
}
///
/// 当获得技能时
///
///
public void OnSkillGained(ActionQueue queue)
{
ActionQueue = queue;
OnLevelUp();
}
///
/// 技能开始吟唱时 [ 吟唱魔法、释放战技和爆发技、预释放爆发技均可触发 ]
///
public void OnSkillCasting(ActionQueue queue, Character caster)
{
ActionQueue = queue;
foreach (Effect e in Effects)
{
e.ActionQueue = ActionQueue;
e.OnSkillCasting(caster);
}
}
///
/// 触发技能效果
///
public void OnSkillCasted(ActionQueue queue, Character caster, List enemys, List teammates)
{
ActionQueue = queue;
foreach (Effect e in Effects)
{
e.ActionQueue = ActionQueue;
e.OnSkillCasted(caster, enemys, teammates, OtherArgs);
}
}
///
/// 被动技能,需要重写此方法,返回被动特效给角色 [ 此方法会在技能学习时触发 ]
///
///
public virtual IEnumerable AddInactiveEffectToCharacter()
{
return [];
}
///
/// 返回技能的详细说明
///
///
public override string ToString()
{
StringBuilder builder = new();
string type = IsSuperSkill ? "【爆发技】" : (IsMagic ? "【魔法】" : (IsActive ? "【主动】" : "【被动】"));
string level = Level > 0 ? " - 等级 " + Level : " - 尚未学习";
builder.AppendLine(type + Name + level);
builder.AppendLine("技能描述:" + Description);
if (CurrentCD > 0)
{
builder.AppendLine($"正在冷却:剩余 {CurrentCD:0.##} 时间");
}
if (!Enable)
{
builder.AppendLine("技能当前不可用");
}
if (IsInEffect)
{
builder.AppendLine("效果结束前不可用");
}
if (IsActive)
{
if (SkillType == SkillType.Item)
{
if (RealMPCost > 0)
{
builder.AppendLine($"魔法消耗:{RealMPCost:0.##}");
}
if (RealEPCost > 0)
{
builder.AppendLine($"能量消耗:{RealEPCost:0.##}");
}
}
else
{
if (IsSuperSkill)
{
builder.AppendLine($"能量消耗:{RealEPCost:0.##}");
}
else
{
if (IsMagic)
{
builder.AppendLine($"魔法消耗:{RealMPCost:0.##}");
builder.AppendLine($"吟唱时间:{RealCastTime:0.##}");
}
else
{
builder.AppendLine($"能量消耗:{RealEPCost:0.##}");
}
}
}
builder.AppendLine($"冷却时间:{RealCD:0.##}");
builder.AppendLine($"硬直时间:{HardnessTime:0.##}");
}
return builder.ToString();
}
///
/// Id.Name
///
///
public string GetIdName()
{
return Id + "." + Name;
}
///
/// 判断两个技能是否相同 检查Id.Name
///
///
///
public override bool Equals(IBaseEntity? other)
{
return other is Skill c && c.Id + "." + c.Name == Id + "." + Name;
}
///
/// 复制一个技能
///
///
public Skill Copy()
{
Skill s = new()
{
Id = Id,
Name = Name,
Description = Description,
GeneralDescription = GeneralDescription,
SkillType = SkillType,
MPCost = MPCost,
CastTime = CastTime,
EPCost = EPCost,
CD = CD,
CurrentCD = CurrentCD,
HardnessTime = HardnessTime,
ActionQueue = ActionQueue
};
foreach (Effect e in Effects)
{
Effect neweffect = e.Copy(s);
s.Effects.Add(neweffect);
}
return s;
}
///
/// 等级
///
private int _Level = 0;
}
}