using System.Text;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Entity
{
public class NormalAttack(Character character, bool isMagic = false, MagicType magicType = MagicType.None) : BaseEntity, ISkill
{
///
/// 普通攻击名称
///
public override string Name => "普通攻击";
///
/// 普通攻击说明
///
public string Description => $"对目标敌人造成 {BaseDamageMultiplier * 100:0.##}% 攻击力 [ {Damage:0.##} ] 点{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "物理伤害")}。";
///
/// 普通攻击的通用说明
///
public string GeneralDescription => $"对目标敌人造成基于总攻击力的{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "物理伤害")}。";
///
/// 所属的角色
///
public Character Character { get; } = character;
///
/// 基础普通攻击伤害倍率 [ 武器类型相关 ]
///
private double BaseDamageMultiplier
{
get
{
double baseMultiplier = 1.0 + 0.05 * (Level - 1);
if (Character.EquipSlot.Weapon != null)
{
baseMultiplier = Character.EquipSlot.Weapon.WeaponType switch
{
WeaponType.OneHandedSword => 1.0,
WeaponType.TwoHandedSword => 1.2,
WeaponType.Bow => 0.9,
WeaponType.Pistol => 0.8,
WeaponType.Rifle => 1.1,
WeaponType.DualDaggers => 0.85,
WeaponType.Talisman => 1.0,
WeaponType.Staff => 1.15,
WeaponType.Polearm => 0.95,
WeaponType.Gauntlet => 1.05,
WeaponType.HiddenWeapon => 0.9,
_ => 1.0
};
double levelBonus = Character.EquipSlot.Weapon.WeaponType switch
{
WeaponType.TwoHandedSword => 0.06,
WeaponType.Staff => 0.056,
WeaponType.Bow => 0.045,
WeaponType.Pistol => 0.0375,
WeaponType.DualDaggers => 0.0375,
WeaponType.Polearm => 0.044,
WeaponType.HiddenWeapon => 0.044,
_ => 0.05
};
baseMultiplier += levelBonus * (Level - 1);
}
return baseMultiplier;
}
}
///
/// 普通攻击的伤害
///
public double Damage => Character.ATK * BaseDamageMultiplier * (1 + ExDamage2) + ExDamage;
///
/// 额外普通攻击伤害 [ 技能和物品相关 ]
///
public double ExDamage { get; set; } = 0;
///
/// 额外普通攻击伤害% [ 技能和物品相关 ]
///
public double ExDamage2 { get; set; } = 0;
///
/// 普通攻击等级
///
public int Level
{
get
{
return Math.Max(1, _Level);
}
set
{
_Level = Math.Min(Math.Max(1, value), GameplayEquilibriumConstant.MaxNormalAttackLevel);
}
}
///
/// 是否是魔法伤害
///
public bool IsMagic => _IsMagic;
///
/// 魔法伤害需要指定魔法类型
///
public MagicType MagicType => _MagicType;
///
/// 是否可用
///
public bool Enable { get; set; } = true;
///
/// 是否在持续生效,为 true 时不允许再次使用。普通攻击始终为 false
///
public bool IsInEffect => false;
///
/// 无视免疫类型
///
public ImmuneType IgnoreImmune { get; set; } = ImmuneType.None;
///
/// 硬直时间 [ 武器类型相关 ]
///
public double HardnessTime
{
get
{
double ht = 10;
if (Character.EquipSlot.Weapon != null)
{
ht = Character.EquipSlot.Weapon.WeaponType switch
{
WeaponType.OneHandedSword => 8,
WeaponType.TwoHandedSword => 12,
WeaponType.Bow => 9,
WeaponType.Pistol => 6,
WeaponType.Rifle => 11,
WeaponType.DualDaggers => 7,
WeaponType.Talisman => 10,
WeaponType.Staff => 12,
WeaponType.Polearm => 10,
WeaponType.Gauntlet => 8,
WeaponType.HiddenWeapon => 7,
_ => 10,
};
}
return ht * (1 + ExHardnessTime2) + ExHardnessTime;
}
}
///
/// 额外硬直时间 [ 技能和物品相关 ]
///
public double ExHardnessTime { get; set; } = 0;
///
/// 额外硬直时间% [ 技能和物品相关 ]
///
public double ExHardnessTime2 { get; set; } = 0;
///
/// 实际硬直时间
///
public double RealHardnessTime => Math.Max(0, HardnessTime * (1 - Calculation.PercentageCheck(Character?.ActionCoefficient ?? 0)));
///
/// 可选取自身
///
public bool CanSelectSelf { get; set; } = false;
///
/// 可选取敌对角色
///
public bool CanSelectEnemy { get; set; } = true;
///
/// 可选取友方角色
///
public bool CanSelectTeammate { get; set; } = false;
///
/// 可选取的作用目标数量
///
public int CanSelectTargetCount { get; set; } = 1;
///
/// 可选取的作用范围
///
public double CanSelectTargetRange { get; set; } = 0;
///
/// 普通攻击没有魔法消耗
///
public double RealMPCost => 0;
///
/// 普通攻击没有吟唱时间
///
public double RealCastTime => 0;
///
/// 普通攻击没有能量消耗
///
public double RealEPCost => 0;
///
/// 普通攻击没有冷却时间
///
public double RealCD => 0;
///
/// 普通攻击没有冷却时间
///
public double CurrentCD => 0;
///
/// 绑定到特效的普通攻击扩展。键为特效,值为对应的普攻扩展对象。
///
public Dictionary NormalAttackOfEffects { get; } = [];
///
/// 获取可选择的目标列表
///
///
///
///
///
public List GetSelectableTargets(Character caster, List enemys, List teammates)
{
List selectable = [];
if (CanSelectSelf)
{
selectable.Add(caster);
}
foreach (Character character in enemys)
{
if (CanSelectEnemy && ((character.ImmuneType & ImmuneType.All) != ImmuneType.All || IgnoreImmune == ImmuneType.All))
{
selectable.Add(character);
}
}
foreach (Character character in teammates)
{
if (CanSelectTeammate && ((character.ImmuneType & ImmuneType.All) != ImmuneType.All || IgnoreImmune == ImmuneType.All))
{
selectable.Add(character);
}
}
return selectable;
}
///
/// 对目标(或多个目标)发起普通攻击
///
///
///
///
public void Attack(IGamingQueue queue, Character attacker, params IEnumerable enemys)
{
if (!Enable)
{
return;
}
foreach (Character enemy in enemys)
{
if (enemy.HP > 0)
{
queue.WriteLine($"[ {Character} ] 对 [ {enemy} ] 发起了普通攻击!");
double expected = Damage;
int changeCount = 0;
DamageResult result = IsMagic ? queue.CalculateMagicalDamage(attacker, enemy, true, MagicType, expected, out double damage, ref changeCount) : queue.CalculatePhysicalDamage(attacker, enemy, true, expected, out damage, ref changeCount);
queue.DamageToEnemyAsync(attacker, enemy, damage, true, IsMagic ? DamageType.Magical : DamageType.Physical, MagicType, result);
}
}
}
///
/// 修改基础伤害类型。不一定转换成功,要看是否有特效覆盖
///
///
///
///
public void SetMagicType(bool? isMagic, MagicType? magicType = null, IGamingQueue? queue = null)
{
_ExIsMagic = isMagic;
if (isMagic.HasValue && isMagic.Value)
{
magicType ??= MagicType.None;
}
_ExMagicType = magicType;
ResolveMagicType(queue);
}
///
/// 修改伤害类型。不一定转换成功,要看是否有其他特效覆盖
///
///
///
public void SetMagicType(NormalAttackOfEffect naoe, IGamingQueue? queue = null)
{
NormalAttackOfEffects[naoe.Effect] = naoe;
ResolveMagicType(queue);
}
///
/// 移除特效对伤害类型的更改
///
///
///
public void UnsetMagicType(Effect effect, IGamingQueue? queue = null)
{
NormalAttackOfEffects.Remove(effect);
ResolveMagicType(queue);
}
///
/// 计算是否是魔法伤害和当前的魔法类型
///
internal void ResolveMagicType(IGamingQueue? queue = null)
{
bool past = _IsMagic;
MagicType pastType = _MagicType;
if (NormalAttackOfEffects.Count > 0)
{
if (NormalAttackOfEffects.Values.OrderByDescending(n => n.Priority).FirstOrDefault() is NormalAttackOfEffect naoe)
{
_IsMagic = naoe.IsMagic;
_MagicType = naoe.MagicType;
}
}
else if (_ExIsMagic.HasValue && _ExMagicType.HasValue)
{
_IsMagic = _ExIsMagic.Value;
_MagicType = _ExMagicType.Value;
}
else
{
_IsMagic = false;
_MagicType = MagicType.None;
if (Character.EquipSlot.Weapon != null)
{
WeaponType type = Character.EquipSlot.Weapon.WeaponType;
if (type == WeaponType.Talisman || type == WeaponType.Staff)
{
_IsMagic = true;
}
}
}
if (queue != null && (past != _IsMagic || pastType != _MagicType))
{
queue.WriteLine($"[ {Character} ] 的普通攻击类型已转变为:{(_IsMagic ? CharacterSet.GetMagicDamageName(_MagicType) : "物理伤害")}!");
}
}
///
/// 比较两个普攻对象
///
///
///
public override bool Equals(IBaseEntity? other)
{
return other is NormalAttack c && c.Name == Name;
}
///
/// 输出信息
///
///
///
public string GetInfo(bool showOriginal = false)
{
StringBuilder builder = new();
builder.AppendLine($"{Name} - 等级 {Level}");
builder.AppendLine($"描述:{Description}");
builder.AppendLine($"硬直时间:{RealHardnessTime:0.##}{(showOriginal && RealHardnessTime != HardnessTime ? $"(原始值:{HardnessTime})" : "")}");
return builder.ToString();
}
///
/// 输出信息
///
///
public override string ToString() => GetInfo(true);
///
/// 等级
///
private int _Level = 0;
///
/// 是否是魔法伤害 [ 生效型 ]
///
private bool _IsMagic = isMagic;
///
/// 魔法类型 [ 生效型 ]
///
private MagicType _MagicType = magicType;
///
/// 是否是魔法伤害 [ 修改型 ]
///
private bool? _ExIsMagic = null;
///
/// 魔法类型 [ 修改型 ]
///
private MagicType? _ExMagicType = null;
}
///
/// 绑定到特效的普通攻击扩展。这个类没有 JSON 转换器支持。
///
public class NormalAttackOfEffect(Effect effect, bool isMagic, MagicType type, int priority)
{
public Effect Effect { get; set; } = effect;
public bool IsMagic { get; set; } = isMagic;
public MagicType MagicType { get; set; } = type;
public int Priority { get; set; } = priority;
}
}