普攻机制更改;魔抗优化

This commit is contained in:
milimoe 2025-06-21 05:15:52 +08:00
parent 496f5d0675
commit ed222e3e1b
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
11 changed files with 338 additions and 147 deletions

View File

@ -780,7 +780,9 @@ namespace Milimoe.FunGame.Core.Api.Utility
/// <returns></returns> /// <returns></returns>
public static double Round(double value, int digits) public static double Round(double value, int digits)
{ {
return Math.Round(value, digits, MidpointRounding.AwayFromZero); value = Math.Round(value, digits, MidpointRounding.AwayFromZero);
if (IsApproximatelyZero(value)) value = 0;
return value;
} }
/// <summary> /// <summary>

View File

@ -1249,6 +1249,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
effect.OnAttributeChanged(this); effect.OnAttributeChanged(this);
} }
NormalAttack.ResolveMagicType();
} }
/// <summary> /// <summary>
@ -1391,7 +1392,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : "")); builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
double exDEF = ExDEF + ExDEF2 + ExDEF3; double exDEF = ExDEF + ExDEF2 + ExDEF3;
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)"); builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
builder.AppendLine($"魔法抗性:{MDF.Avg:0.##}%(平均)"); builder.AppendLine(GetMagicResistanceInfo().Trim());
double exSPD = AGI * GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD; double exSPD = AGI * GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD;
builder.AppendLine($"行动速度:{SPD:0.##}" + (exSPD != 0 ? $" [{InitialSPD:0.##} {(exSPD >= 0 ? "+" : "-")} {Math.Abs(exSPD):0.##}]" : "") + $" ({ActionCoefficient * 100:0.##}%)"); builder.AppendLine($"行动速度:{SPD:0.##}" + (exSPD != 0 ? $" [{InitialSPD:0.##} {(exSPD >= 0 ? "+" : "-")} {Math.Abs(exSPD):0.##}]" : "") + $" ({ActionCoefficient * 100:0.##}%)");
builder.AppendLine($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}"); builder.AppendLine($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
@ -1443,46 +1444,12 @@ namespace Milimoe.FunGame.Core.Entity
if (EquipSlot.Any()) if (EquipSlot.Any())
{ {
builder.AppendLine("== 装备栏 =="); builder.AppendLine(GetEquipSlotInfo().Trim());
if (EquipSlot.MagicCardPack != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.MagicCardPack.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.MagicCardPack) + "" + EquipSlot.MagicCardPack.Name);
builder.AppendLine(EquipSlot.MagicCardPack.Description);
}
if (EquipSlot.Weapon != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Weapon.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Weapon) + "" + EquipSlot.Weapon.Name);
builder.AppendLine(EquipSlot.Weapon.Description);
}
if (EquipSlot.Armor != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Armor.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Armor) + "" + EquipSlot.Armor.Name);
builder.AppendLine(EquipSlot.Armor.Description);
}
if (EquipSlot.Shoes != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Shoes.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Shoes) + "" + EquipSlot.Shoes.Name);
builder.AppendLine(EquipSlot.Shoes.Description);
}
if (EquipSlot.Accessory1 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory1.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory1) + "" + EquipSlot.Accessory1.Name);
builder.AppendLine(EquipSlot.Accessory1.Description);
}
if (EquipSlot.Accessory2 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory2.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory2) + "" + EquipSlot.Accessory2.Name);
builder.AppendLine(EquipSlot.Accessory2.Description);
}
} }
if (Items.Count > 0) if (Items.Count > 0)
{ {
builder.AppendLine("== 角色背包 =="); builder.AppendLine(GetBackpackItemsInfo().Trim());
foreach (Item item in Items)
{
builder.Append(item.ToString());
}
} }
Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)]; Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
@ -1525,7 +1492,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : "")); builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
double exDEF = ExDEF + ExDEF2 + ExDEF3; double exDEF = ExDEF + ExDEF2 + ExDEF3;
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)"); builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
builder.AppendLine($"魔法抗性:{MDF.Avg:0.##}%(平均)"); builder.AppendLine(GetMagicResistanceInfo().Trim());
if (showBasicOnly) if (showBasicOnly)
{ {
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}"); builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
@ -1774,7 +1741,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : "")); builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
double exDEF = ExDEF + ExDEF2 + ExDEF3; double exDEF = ExDEF + ExDEF2 + ExDEF3;
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)"); builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
builder.AppendLine($"魔法抗性:{MDF.Avg:0.##}%(平均)"); builder.AppendLine(GetMagicResistanceInfo().Trim());
double exSPD = AGI * GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD; double exSPD = AGI * GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD;
builder.AppendLine($"行动速度:{SPD:0.##}" + (exSPD != 0 ? $" [{InitialSPD:0.##} {(exSPD >= 0 ? "+" : "-")} {Math.Abs(exSPD):0.##}]" : "") + $" ({ActionCoefficient * 100:0.##}%)"); builder.AppendLine($"行动速度:{SPD:0.##}" + (exSPD != 0 ? $" [{InitialSPD:0.##} {(exSPD >= 0 ? "+" : "-")} {Math.Abs(exSPD):0.##}]" : "") + $" ({ActionCoefficient * 100:0.##}%)");
builder.AppendLine($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}"); builder.AppendLine($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
@ -1799,51 +1766,109 @@ namespace Milimoe.FunGame.Core.Entity
if (EquipSlot.Any()) if (EquipSlot.Any())
{ {
builder.AppendLine("== 装备栏 =="); builder.AppendLine(GetEquipSlotInfo().Trim());
if (EquipSlot.MagicCardPack != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.MagicCardPack.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.MagicCardPack) + "" + EquipSlot.MagicCardPack.Name);
builder.AppendLine(EquipSlot.MagicCardPack.Description);
}
if (EquipSlot.Weapon != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Weapon.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Weapon) + "" + EquipSlot.Weapon.Name);
builder.AppendLine(EquipSlot.Weapon.Description);
}
if (EquipSlot.Armor != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Armor.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Armor) + "" + EquipSlot.Armor.Name);
builder.AppendLine(EquipSlot.Armor.Description);
}
if (EquipSlot.Shoes != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Shoes.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Shoes) + "" + EquipSlot.Shoes.Name);
builder.AppendLine(EquipSlot.Shoes.Description);
}
if (EquipSlot.Accessory1 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory1.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory1) + "" + EquipSlot.Accessory1.Name);
builder.AppendLine(EquipSlot.Accessory1.Description);
}
if (EquipSlot.Accessory2 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory2.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory2) + "" + EquipSlot.Accessory2.Name);
builder.AppendLine(EquipSlot.Accessory2.Description);
}
} }
if (Items.Count > 0) if (Items.Count > 0)
{ {
builder.AppendLine("== 角色背包 =="); builder.AppendLine(GetBackpackItemsInfo().Trim());
foreach (Item item in Items) }
return builder.ToString();
}
/// <summary>
/// 获取角色装备栏信息
/// </summary>
/// <returns></returns>
public string GetEquipSlotInfo()
{
StringBuilder builder = new();
builder.AppendLine("== 装备栏 ==");
if (EquipSlot.MagicCardPack != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.MagicCardPack.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.MagicCardPack) + "" + EquipSlot.MagicCardPack.Name);
builder.AppendLine(EquipSlot.MagicCardPack.Description);
}
if (EquipSlot.Weapon != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Weapon.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Weapon) + "" + EquipSlot.Weapon.Name);
builder.AppendLine(EquipSlot.Weapon.Description);
}
if (EquipSlot.Armor != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Armor.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Armor) + "" + EquipSlot.Armor.Name);
builder.AppendLine(EquipSlot.Armor.Description);
}
if (EquipSlot.Shoes != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Shoes.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Shoes) + "" + EquipSlot.Shoes.Name);
builder.AppendLine(EquipSlot.Shoes.Description);
}
if (EquipSlot.Accessory1 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory1.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory1) + "" + EquipSlot.Accessory1.Name);
builder.AppendLine(EquipSlot.Accessory1.Description);
}
if (EquipSlot.Accessory2 != null)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(EquipSlot.Accessory2.QualityType)}]" + ItemSet.GetEquipSlotTypeName(EquipSlotType.Accessory2) + "" + EquipSlot.Accessory2.Name);
builder.AppendLine(EquipSlot.Accessory2.Description);
}
return builder.ToString();
}
/// <summary>
/// 获取角色背包信息
/// </summary>
/// <returns></returns>
public string GetBackpackItemsInfo()
{
StringBuilder builder = new();
builder.AppendLine("== 角色背包 ==");
foreach (Item item in Items)
{
builder.AppendLine($"[{ItemSet.GetQualityTypeName(item.QualityType)}]" + ItemSet.GetItemTypeName(item.ItemType) + "" + item.Name);
builder.AppendLine(item.Description);
if (item.Skills.Active != null)
{ {
builder.Append(item.ToString()); Skill skill = item.Skills.Active;
List<string> strings = [];
if (skill.RealMPCost > 0) strings.Add($"魔法消耗:{skill.RealMPCost}");
if (skill.RealEPCost > 0) strings.Add($"能量消耗:{skill.RealEPCost}");
if (skill.RealCD > 0) strings.Add($"冷却时间:{skill.RealCD}{(skill.CurrentCD > 0 ? $" {skill.CurrentCD} {GameplayEquilibriumConstant.InGameTime}" : "")}");
if (skill.RealHardnessTime > 0) strings.Add($"硬直时间:{skill.RealHardnessTime}");
builder.AppendLine($"技能【{skill.Name}】描述:{skill.Description.Trim()}{(strings.Count > 0 ? $"{string.Join("", strings)}" : "")}");
} }
} }
return builder.ToString(); return builder.ToString();
} }
/// <summary>
/// 获取魔法抗性信息
/// </summary>
/// <returns></returns>
public string GetMagicResistanceInfo()
{
StringBuilder builder = new();
if (GameplayEquilibriumConstant.UseMagicType.Count > 0)
{
foreach (MagicType magicType in GameplayEquilibriumConstant.UseMagicType)
{
builder.Append(CharacterSet.GetMagicResistanceName(magicType));
builder.AppendLine($"{Calculation.Round4Digits(MDF[magicType] * 100):0.##}%");
}
}
else builder.AppendLine($"魔法抗性:{Calculation.Round4Digits(MDF.Avg * 100):0.##}%(平均)");
return builder.ToString();
}
/// <summary> /// <summary>
/// 更新角色的状态,参见 <see cref="CharacterEffectStates"/>、<see cref="CharacterEffectTypes"/> 用法 /// 更新角色的状态,参见 <see cref="CharacterEffectStates"/>、<see cref="CharacterEffectTypes"/> 用法
/// </summary> /// </summary>

View File

@ -252,7 +252,10 @@ namespace Milimoe.FunGame.Core.Entity
character.EXP = reference.EXP; character.EXP = reference.EXP;
} }
character.NormalAttack.Level = reference.NormalAttack.Level; character.NormalAttack.Level = reference.NormalAttack.Level;
character.NormalAttack.HardnessTime = reference.NormalAttack.HardnessTime; character.NormalAttack.ExDamage = reference.NormalAttack.ExDamage;
character.NormalAttack.ExDamage2 = reference.NormalAttack.ExDamage2;
character.NormalAttack.ExHardnessTime = reference.NormalAttack.ExHardnessTime;
character.NormalAttack.ExHardnessTime2 = reference.NormalAttack.ExHardnessTime2;
character.NormalAttack.SetMagicType(reference.NormalAttack.IsMagic, reference.NormalAttack.MagicType); character.NormalAttack.SetMagicType(reference.NormalAttack.IsMagic, reference.NormalAttack.MagicType);
if (!recovery) if (!recovery)
{ {

View File

@ -60,7 +60,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double mdf = Calculation.Round4Digits((None + Starmark + PurityNatural + PurityContemporary + Bright + Shadow + Element + Aster + SpatioTemporal) / 9) * 100; double mdf = Calculation.Round4Digits((None + Starmark + PurityNatural + PurityContemporary + Bright + Shadow + Element + Aster + SpatioTemporal) / 9);
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
return mdf; return mdf;
} }
@ -123,39 +123,6 @@ namespace Milimoe.FunGame.Core.Entity
} }
} }
/// <summary>
/// 对所有抗性赋值
/// </summary>
/// <param name="value"></param>
/// <param name="assignment"></param>
public void SetAllValue(double value, bool assignment = true)
{
if (assignment)
{
None = value;
SpatioTemporal = value;
Aster = value;
Element = value;
Shadow = value;
Bright = value;
PurityContemporary = value;
PurityNatural = value;
Starmark = value;
}
else
{
None += value;
SpatioTemporal += value;
Aster += value;
Element += value;
Shadow += value;
Bright += value;
PurityContemporary += value;
PurityNatural += value;
Starmark += value;
}
}
/// <summary> /// <summary>
/// 增加所有抗性,传入负数来减少 /// 增加所有抗性,传入负数来减少
/// </summary> /// </summary>
@ -163,14 +130,14 @@ namespace Milimoe.FunGame.Core.Entity
public void AddAllValue(double value) public void AddAllValue(double value)
{ {
None += value; None += value;
SpatioTemporal += value;
Aster += value;
Element += value;
Shadow += value;
Bright += value;
PurityContemporary += value;
PurityNatural += value;
Starmark += value; Starmark += value;
PurityNatural += value;
PurityContemporary += value;
Element += value;
Bright += value;
Shadow += value;
Aster += value;
SpatioTemporal += value;
} }
/// <summary> /// <summary>

View File

@ -176,18 +176,10 @@ namespace Milimoe.FunGame.Core.Entity
foreach (Skill skill in Skills.Passives) foreach (Skill skill in Skills.Passives)
{ {
skill.Character = _character; skill.Character = _character;
foreach (Effect e in skill.Effects)
{
e.Source = _character;
}
} }
foreach (Skill skill in Skills.Magics) foreach (Skill skill in Skills.Magics)
{ {
skill.Character = _character; skill.Character = _character;
foreach (Effect e in skill.Effects)
{
e.Source = _character;
}
} }
} }
} }

View File

@ -16,22 +16,74 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 普通攻击说明 /// 普通攻击说明
/// </summary> /// </summary>
public string Description => $"对目标敌人造成 {(1.0 + 0.05 * (Level - 1)) * 100:0.##}% 攻击力 [ {Damage:0.##} ] 点{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "")}。"; public string Description => $"对目标敌人造成 {BaseDamageMultiplier * 100:0.##}% 攻击力 [ {Damage:0.##} ] 点{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "")}。";
/// <summary> /// <summary>
/// 普通攻击的通用说明 /// 普通攻击的通用说明
/// </summary> /// </summary>
public string GeneralDescription => $"对目标敌人造成基于 100+5/Lv% 攻击力的{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "")}。"; public string GeneralDescription => $"对目标敌人造成基于攻击力的{(IsMagic ? CharacterSet.GetMagicDamageName(MagicType) : "")}。";
/// <summary> /// <summary>
/// 所属的角色 /// 所属的角色
/// </summary> /// </summary>
public Character Character { get; } = character; public Character Character { get; } = character;
/// <summary>
/// 基础普通攻击伤害倍率 [ 武器类型相关 ]
/// </summary>
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;
}
}
/// <summary> /// <summary>
/// 普通攻击的伤害 /// 普通攻击的伤害
/// </summary> /// </summary>
public double Damage => Character.ATK * (1.0 + 0.05 * (Level - 1)); public double Damage => Character.ATK * BaseDamageMultiplier * (1 + ExDamage2) + ExDamage;
/// <summary>
/// 额外普通攻击伤害 [ 技能和物品相关 ]
/// </summary>
public double ExDamage { get; set; } = 0;
/// <summary>
/// 额外普通攻击伤害% [ 技能和物品相关 ]
/// </summary>
public double ExDamage2 { get; set; } = 0;
/// <summary> /// <summary>
/// 普通攻击等级 /// 普通攻击等级
@ -74,9 +126,44 @@ namespace Milimoe.FunGame.Core.Entity
public ImmuneType IgnoreImmune { get; set; } = ImmuneType.None; public ImmuneType IgnoreImmune { get; set; } = ImmuneType.None;
/// <summary> /// <summary>
/// 硬直时间 /// 硬直时间 [ 武器类型相关 ]
/// </summary> /// </summary>
public double HardnessTime { get; set; } = 10; 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;
}
}
/// <summary>
/// 额外硬直时间 [ 技能和物品相关 ]
/// </summary>
public double ExHardnessTime { get; set; } = 0;
/// <summary>
/// 额外硬直时间% [ 技能和物品相关 ]
/// </summary>
public double ExHardnessTime2 { get; set; } = 0;
/// <summary> /// <summary>
/// 实际硬直时间 /// 实际硬直时间
@ -133,6 +220,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public double CurrentCD => 0; public double CurrentCD => 0;
/// <summary>
/// 绑定到特效的普通攻击扩展。键为特效,值为对应的普攻扩展对象。
/// </summary>
public Dictionary<Effect, NormalAttackOfEffect> NormalAttackOfEffects { get; } = [];
/// <summary> /// <summary>
/// 获取可选择的目标列表 /// 获取可选择的目标列表
/// </summary> /// </summary>
@ -177,7 +269,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
if (enemy.HP > 0) if (enemy.HP > 0)
{ {
queue.WriteLine("[ " + Character + $" ] 对 [ {enemy} ] 发起了普通攻击!"); queue.WriteLine($"[ {Character} ] 对 [ {enemy} ] 发起了普通攻击!");
double expected = Damage; double expected = Damage;
int changeCount = 0; 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); 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);
@ -187,14 +279,81 @@ namespace Milimoe.FunGame.Core.Entity
} }
/// <summary> /// <summary>
/// 修改伤害类型 /// 修改基础伤害类型。不一定转换成功,要看是否有特效覆盖
/// </summary> /// </summary>
/// <param name="isMagic"></param> /// <param name="isMagic"></param>
/// <param name="magicType"></param> /// <param name="magicType"></param>
public void SetMagicType(bool isMagic, MagicType magicType) /// <param name="queue"></param>
public void SetMagicType(bool? isMagic, MagicType? magicType = null, IGamingQueue? queue = null)
{ {
_IsMagic = isMagic; _ExIsMagic = isMagic;
_MagicType = magicType; if (isMagic.HasValue && isMagic.Value)
{
magicType ??= MagicType.None;
}
_ExMagicType = magicType;
ResolveMagicType(queue);
}
/// <summary>
/// 修改伤害类型。不一定转换成功,要看是否有其他特效覆盖
/// </summary>
/// <param name="naoe"></param>
/// <param name="queue"></param>
public void SetMagicType(NormalAttackOfEffect naoe, IGamingQueue? queue = null)
{
NormalAttackOfEffects[naoe.Effect] = naoe;
ResolveMagicType(queue);
}
/// <summary>
/// 移除特效对伤害类型的更改
/// </summary>
/// <param name="effect"></param>
/// <param name="queue"></param>
public void UnsetMagicType(Effect effect, IGamingQueue? queue = null)
{
NormalAttackOfEffects.Remove(effect);
ResolveMagicType(queue);
}
/// <summary>
/// 计算是否是魔法伤害和当前的魔法类型
/// </summary>
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) : "")}");
}
} }
/// <summary> /// <summary>
@ -235,13 +394,34 @@ namespace Milimoe.FunGame.Core.Entity
private int _Level = 0; private int _Level = 0;
/// <summary> /// <summary>
/// 是否是魔法伤害 /// 是否是魔法伤害 [ 生效型 ]
/// </summary> /// </summary>
private bool _IsMagic = isMagic; private bool _IsMagic = isMagic;
/// <summary> /// <summary>
/// 魔法类型 /// 魔法类型 [ 生效型 ]
/// </summary> /// </summary>
private MagicType _MagicType = magicType; private MagicType _MagicType = magicType;
/// <summary>
/// 是否是魔法伤害 [ 修改型 ]
/// </summary>
private bool? _ExIsMagic = null;
/// <summary>
/// 魔法类型 [ 修改型 ]
/// </summary>
private MagicType? _ExMagicType = null;
}
/// <summary>
/// 绑定到特效的普通攻击扩展。这个类没有 JSON 转换器支持。
/// </summary>
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;
} }
} }

View File

@ -481,39 +481,39 @@ namespace Milimoe.FunGame.Core.Entity
{ {
if (RealMPCost > 0) if (RealMPCost > 0)
{ {
builder.AppendLine($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"{MPCost}" : "")}"); builder.AppendLine($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"{MPCost:0.##}" : "")}");
} }
if (RealEPCost > 0) if (RealEPCost > 0)
{ {
builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost}" : "")}"); builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost:0.##}" : "")}");
} }
} }
else else
{ {
if (IsSuperSkill) if (IsSuperSkill)
{ {
builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost}" : "")}"); builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost:0.##}" : "")}");
} }
else else
{ {
if (IsMagic) if (IsMagic)
{ {
builder.AppendLine($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"{MPCost}" : "")}"); builder.AppendLine($"魔法消耗:{RealMPCost:0.##}{(showOriginal && RealMPCost != MPCost ? $"{MPCost:0.##}" : "")}");
builder.AppendLine($"吟唱时间:{RealCastTime:0.##}{(showOriginal && RealCastTime != CastTime ? $"{CastTime}" : "")}"); builder.AppendLine($"吟唱时间:{RealCastTime:0.##}{(showOriginal && RealCastTime != CastTime ? $"{CastTime:0.##}" : "")}");
} }
else else
{ {
builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost}" : "")}"); builder.AppendLine($"能量消耗:{RealEPCost:0.##}{(showOriginal && RealEPCost != EPCost ? $"{EPCost:0.##}" : "")}");
} }
} }
} }
if (showCD && CD > 0) if (showCD && CD > 0)
{ {
builder.AppendLine($"冷却时间:{RealCD:0.##}{(showOriginal && RealCD != CD ? $"{CD}" : "")}"); builder.AppendLine($"冷却时间:{RealCD:0.##}{(showOriginal && RealCD != CD ? $"{CD:0.##}" : "")}");
} }
if (showHardness && HardnessTime > 0) if (showHardness && HardnessTime > 0)
{ {
builder.AppendLine($"硬直时间:{RealHardnessTime:0.##}{(showOriginal && RealHardnessTime != HardnessTime ? $"{HardnessTime}" : "")}"); builder.AppendLine($"硬直时间:{RealHardnessTime:0.##}{(showOriginal && RealHardnessTime != HardnessTime ? $"{HardnessTime:0.##}" : "")}");
} }
} }

View File

@ -218,7 +218,10 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(Character.NormalAttack): case nameof(Character.NormalAttack):
NormalAttack normalAttack = NetworkUtility.JsonDeserialize<NormalAttack>(ref reader, options) ?? new NormalAttack(result); NormalAttack normalAttack = NetworkUtility.JsonDeserialize<NormalAttack>(ref reader, options) ?? new NormalAttack(result);
result.NormalAttack.Level = normalAttack.Level; result.NormalAttack.Level = normalAttack.Level;
result.NormalAttack.HardnessTime = normalAttack.HardnessTime; result.NormalAttack.ExDamage = normalAttack.ExDamage;
result.NormalAttack.ExDamage2 = normalAttack.ExDamage2;
result.NormalAttack.ExHardnessTime = normalAttack.ExHardnessTime;
result.NormalAttack.ExHardnessTime2 = normalAttack.ExHardnessTime2;
result.NormalAttack.SetMagicType(normalAttack.IsMagic, normalAttack.MagicType); result.NormalAttack.SetMagicType(normalAttack.IsMagic, normalAttack.MagicType);
break; break;
case nameof(Character.Skills): case nameof(Character.Skills):

View File

@ -20,8 +20,17 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter
case nameof(NormalAttack.Level): case nameof(NormalAttack.Level):
result.Level = reader.GetInt32(); result.Level = reader.GetInt32();
break; break;
case nameof(NormalAttack.HardnessTime): case nameof(NormalAttack.ExDamage):
result.HardnessTime = reader.GetDouble(); result.ExDamage = reader.GetDouble();
break;
case nameof(NormalAttack.ExDamage2):
result.ExDamage2 = reader.GetDouble();
break;
case nameof(NormalAttack.ExHardnessTime):
result.ExHardnessTime = reader.GetDouble();
break;
case nameof(NormalAttack.ExHardnessTime2):
result.ExHardnessTime2 = reader.GetDouble();
break; break;
case nameof(NormalAttack.IsMagic): case nameof(NormalAttack.IsMagic):
result.SetMagicType(reader.GetBoolean(), result.MagicType); result.SetMagicType(reader.GetBoolean(), result.MagicType);

View File

@ -1,4 +1,5 @@
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Core.Model namespace Milimoe.FunGame.Core.Model
{ {
@ -37,6 +38,14 @@ namespace Milimoe.FunGame.Core.Model
{ "E", 200 }, { "E", 200 },
}; };
/// <summary>
/// 使用的魔法类型
/// </summary>
public HashSet<MagicType> UseMagicType { get; set; } = [
MagicType.None, MagicType.Starmark, MagicType.PurityNatural, MagicType.PurityContemporary,
MagicType.Element, MagicType.Bright, MagicType.Shadow, MagicType.Aster, MagicType.SpatioTemporal
];
/// <summary> /// <summary>
/// 初始生命值 /// 初始生命值
/// </summary> /// </summary>

View File

@ -471,6 +471,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
FirstKiller = null; FirstKiller = null;
CustomData.Clear(); CustomData.Clear();
_allCharacter.Clear();
_original.Clear(); _original.Clear();
_queue.Clear(); _queue.Clear();
_hardnessTimes.Clear(); _hardnessTimes.Clear();