平衡常数类下放至实体/模型级别管理;行动顺序表模型大幅优化(区别自动化) (#125)

This commit is contained in:
milimoe 2025-04-11 01:08:35 +08:00 committed by GitHub
parent b01c705187
commit 0cc6ca5144
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 494 additions and 194 deletions

View File

@ -1,5 +1,6 @@
using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Entity namespace Milimoe.FunGame.Core.Entity
{ {
@ -25,6 +26,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public EntityState EntityState { get; set; } = EntityState.Unchanged; public EntityState EntityState { get; set; } = EntityState.Unchanged;
/// <summary>
/// 实体所用的游戏平衡常数
/// </summary>
public EquilibriumConstant GameplayEquilibriumConstant { get; set; } = General.GameplayEquilibriumConstant;
/// <summary> /// <summary>
/// 比较两个实体是否相同 /// 比较两个实体是否相同
/// </summary> /// </summary>

View File

@ -73,31 +73,31 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["S"]) if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["S"])
{ {
return RoleRating.X; return RoleRating.X;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["A+"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["S"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["A+"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["S"])
{ {
return RoleRating.S; return RoleRating.S;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["A"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["A+"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["A"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["A+"])
{ {
return RoleRating.APlus; return RoleRating.APlus;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["B"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["A"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["B"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["A"])
{ {
return RoleRating.A; return RoleRating.A;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["C"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["B"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["C"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["B"])
{ {
return RoleRating.B; return RoleRating.B;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["D"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["C"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["D"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["C"])
{ {
return RoleRating.C; return RoleRating.C;
} }
else if (Promotion > General.GameplayEquilibriumConstant.PromotionsUpperLimit["E"] && Promotion <= General.GameplayEquilibriumConstant.PromotionsUpperLimit["D"]) else if (Promotion > GameplayEquilibriumConstant.PromotionsUpperLimit["E"] && Promotion <= GameplayEquilibriumConstant.PromotionsUpperLimit["D"])
{ {
return RoleRating.D; return RoleRating.D;
} }
@ -129,7 +129,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
set set
{ {
_Level = Math.Min(Math.Max(1, value), General.GameplayEquilibriumConstant.MaxLevel); _Level = Math.Min(Math.Max(1, value), GameplayEquilibriumConstant.MaxLevel);
OnAttributeChanged(); OnAttributeChanged();
Recovery(); Recovery();
} }
@ -174,17 +174,17 @@ namespace Milimoe.FunGame.Core.Entity
/// 初始生命值 [ 初始设定 ] /// 初始生命值 [ 初始设定 ]
/// </summary> /// </summary>
[InitRequired] [InitRequired]
public double InitialHP { get; set; } = General.GameplayEquilibriumConstant.InitialHP; public double InitialHP { get; set; } = 0;
/// <summary> /// <summary>
/// 基础生命值 [ 与初始设定和等级相关 ] [ 与基础力量相关 ] /// 基础生命值 [ 与初始设定和等级相关 ] [ 与基础力量相关 ]
/// </summary> /// </summary>
public double BaseHP => InitialHP + (Level - 1) * (General.GameplayEquilibriumConstant.LevelToHPFactor + General.GameplayEquilibriumConstant.HPGrowthFactor * InitialHP) + BaseSTR * General.GameplayEquilibriumConstant.STRtoHPFactor; public double BaseHP => InitialHP + (Level - 1) * (GameplayEquilibriumConstant.LevelToHPFactor + GameplayEquilibriumConstant.HPGrowthFactor * InitialHP) + BaseSTR * GameplayEquilibriumConstant.STRtoHPFactor;
/// <summary> /// <summary>
/// 额外生命值 [ 与额外力量相关 ] /// 额外生命值 [ 与额外力量相关 ]
/// </summary> /// </summary>
public double ExHP => ExSTR * General.GameplayEquilibriumConstant.STRtoHPFactor; public double ExHP => ExSTR * GameplayEquilibriumConstant.STRtoHPFactor;
/// <summary> /// <summary>
/// 额外生命值2 [ 与技能和物品相关 ] /// 额外生命值2 [ 与技能和物品相关 ]
@ -227,17 +227,17 @@ namespace Milimoe.FunGame.Core.Entity
/// 初始魔法值 [ 初始设定 ] /// 初始魔法值 [ 初始设定 ]
/// </summary> /// </summary>
[InitRequired] [InitRequired]
public double InitialMP { get; set; } = General.GameplayEquilibriumConstant.InitialMP; public double InitialMP { get; set; } = 0;
/// <summary> /// <summary>
/// 基础魔法值 [ 与初始设定和等级相关 ] [ 与基础智力相关 ] /// 基础魔法值 [ 与初始设定和等级相关 ] [ 与基础智力相关 ]
/// </summary> /// </summary>
public double BaseMP => InitialMP + (Level - 1) * (General.GameplayEquilibriumConstant.LevelToMPFactor + General.GameplayEquilibriumConstant.MPGrowthFactor * InitialMP) + BaseINT * General.GameplayEquilibriumConstant.INTtoMPFactor; public double BaseMP => InitialMP + (Level - 1) * (GameplayEquilibriumConstant.LevelToMPFactor + GameplayEquilibriumConstant.MPGrowthFactor * InitialMP) + BaseINT * GameplayEquilibriumConstant.INTtoMPFactor;
/// <summary> /// <summary>
/// 额外魔法值 [ 与额外智力相关 ] /// 额外魔法值 [ 与额外智力相关 ]
/// </summary> /// </summary>
public double ExMP => ExINT * General.GameplayEquilibriumConstant.INTtoMPFactor; public double ExMP => ExINT * GameplayEquilibriumConstant.INTtoMPFactor;
/// <summary> /// <summary>
/// 额外魔法值2 [ 与技能和物品相关 ] /// 额外魔法值2 [ 与技能和物品相关 ]
@ -283,12 +283,12 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
return _EP < 0 ? 0 : (_EP > General.GameplayEquilibriumConstant.MaxEP ? General.GameplayEquilibriumConstant.MaxEP : _EP); return _EP < 0 ? 0 : (_EP > GameplayEquilibriumConstant.MaxEP ? GameplayEquilibriumConstant.MaxEP : _EP);
} }
set set
{ {
_EP = value; _EP = value;
if (_EP > General.GameplayEquilibriumConstant.MaxEP) _EP = General.GameplayEquilibriumConstant.MaxEP; if (_EP > GameplayEquilibriumConstant.MaxEP) _EP = GameplayEquilibriumConstant.MaxEP;
else if (_EP < 0) _EP = 0; else if (_EP < 0) _EP = 0;
} }
} }
@ -297,7 +297,7 @@ namespace Milimoe.FunGame.Core.Entity
/// 初始攻击力 [ 初始设定 ] /// 初始攻击力 [ 初始设定 ]
/// </summary> /// </summary>
[InitRequired] [InitRequired]
public double InitialATK { get; set; } = General.GameplayEquilibriumConstant.InitialATK; public double InitialATK { get; set; } = 0;
/// <summary> /// <summary>
/// 基础攻击力 [ 与初始设定和等级相关 ] [ 与核心属性相关 ] /// 基础攻击力 [ 与初始设定和等级相关 ] [ 与核心属性相关 ]
@ -306,7 +306,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double atk = InitialATK + (Level - 1) * (General.GameplayEquilibriumConstant.LevelToATKFactor + General.GameplayEquilibriumConstant.ATKGrowthFactor * InitialATK); double atk = InitialATK + (Level - 1) * (GameplayEquilibriumConstant.LevelToATKFactor + GameplayEquilibriumConstant.ATKGrowthFactor * InitialATK);
if (PrimaryAttribute == PrimaryAttribute.AGI) if (PrimaryAttribute == PrimaryAttribute.AGI)
{ {
return atk + BaseAGI; return atk + BaseAGI;
@ -368,17 +368,17 @@ namespace Milimoe.FunGame.Core.Entity
/// 初始物理护甲 [ 初始设定 ] /// 初始物理护甲 [ 初始设定 ]
/// </summary> /// </summary>
[InitRequired] [InitRequired]
public double InitialDEF { get; set; } = General.GameplayEquilibriumConstant.InitialDEF; public double InitialDEF { get; set; } = 0;
/// <summary> /// <summary>
/// 基础物理护甲 [ 与初始设定相关 ] [ 与基础力量相关 ] /// 基础物理护甲 [ 与初始设定相关 ] [ 与基础力量相关 ]
/// </summary> /// </summary>
public double BaseDEF => InitialDEF + BaseSTR * General.GameplayEquilibriumConstant.STRtoDEFFactor; public double BaseDEF => InitialDEF + BaseSTR * GameplayEquilibriumConstant.STRtoDEFFactor;
/// <summary> /// <summary>
/// 额外物理护甲 [ 与额外力量相关 ] /// 额外物理护甲 [ 与额外力量相关 ]
/// </summary> /// </summary>
public double ExDEF => ExSTR * General.GameplayEquilibriumConstant.STRtoDEFFactor; public double ExDEF => ExSTR * GameplayEquilibriumConstant.STRtoDEFFactor;
/// <summary> /// <summary>
/// 额外物理护甲2 [ 与技能和物品相关 ] /// 额外物理护甲2 [ 与技能和物品相关 ]
@ -407,7 +407,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = (DEF / (DEF + General.GameplayEquilibriumConstant.DEFReductionFactor)) + ExPDR; double value = (DEF / (DEF + GameplayEquilibriumConstant.DEFReductionFactor)) + ExPDR;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -461,7 +461,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 生命回复力 = [ 与初始设定相关 ] [ 与力量相关 ] + 额外生命回复力 /// 生命回复力 = [ 与初始设定相关 ] [ 与力量相关 ] + 额外生命回复力
/// </summary> /// </summary>
public double HR => InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor + ExHR; public double HR => InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor + ExHR;
/// <summary> /// <summary>
/// 额外生命回复力 [ 与技能和物品相关 ] /// 额外生命回复力 [ 与技能和物品相关 ]
@ -477,7 +477,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 魔法回复力 = [ 与初始设定相关 ] [ 与智力相关 ] + 额外魔法回复力 /// 魔法回复力 = [ 与初始设定相关 ] [ 与智力相关 ] + 额外魔法回复力
/// </summary> /// </summary>
public double MR => InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor + ExMR; public double MR => InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor + ExMR;
/// <summary> /// <summary>
/// 额外魔法回复力 [ 与技能和物品相关 ] /// 额外魔法回复力 [ 与技能和物品相关 ]
@ -672,7 +672,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 行动速度 = [ 与初始设定相关 ][ 与敏捷相关 ] + 额外行动速度 /// 行动速度 = [ 与初始设定相关 ][ 与敏捷相关 ] + 额外行动速度
/// </summary> /// </summary>
public double SPD => InitialSPD + AGI * General.GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD; public double SPD => InitialSPD + AGI * GameplayEquilibriumConstant.AGItoSPDMultiplier + ExSPD;
/// <summary> /// <summary>
/// 额外行动速度 [ 与技能和物品相关 ] /// 额外行动速度 [ 与技能和物品相关 ]
@ -686,7 +686,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = SPD / General.GameplayEquilibriumConstant.SPDUpperLimit + ExActionCoefficient; double value = SPD / GameplayEquilibriumConstant.SPDUpperLimit + ExActionCoefficient;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -703,7 +703,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = INT * General.GameplayEquilibriumConstant.INTtoAccelerationCoefficientMultiplier + ExAccelerationCoefficient; double value = INT * GameplayEquilibriumConstant.INTtoAccelerationCoefficientMultiplier + ExAccelerationCoefficient;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -720,7 +720,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = INT * General.GameplayEquilibriumConstant.INTtoCDRMultiplier + ExCDR; double value = INT * GameplayEquilibriumConstant.INTtoCDRMultiplier + ExCDR;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -743,7 +743,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = General.GameplayEquilibriumConstant.CritRate + AGI * General.GameplayEquilibriumConstant.AGItoCritRateMultiplier + ExCritRate; double value = GameplayEquilibriumConstant.CritRate + AGI * GameplayEquilibriumConstant.AGItoCritRateMultiplier + ExCritRate;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -760,7 +760,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
return General.GameplayEquilibriumConstant.CritDMG + STR * General.GameplayEquilibriumConstant.STRtoCritDMGMultiplier + ExCritDMG; return GameplayEquilibriumConstant.CritDMG + STR * GameplayEquilibriumConstant.STRtoCritDMGMultiplier + ExCritDMG;
} }
} }
@ -776,7 +776,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
get get
{ {
double value = General.GameplayEquilibriumConstant.EvadeRate + AGI * General.GameplayEquilibriumConstant.AGItoEvadeRateMultiplier + ExEvadeRate; double value = GameplayEquilibriumConstant.EvadeRate + AGI * GameplayEquilibriumConstant.AGItoEvadeRateMultiplier + ExEvadeRate;
return Calculation.PercentageCheck(value); return Calculation.PercentageCheck(value);
} }
} }
@ -844,6 +844,10 @@ namespace Milimoe.FunGame.Core.Entity
{ {
User = General.UnknownUserInstance; User = General.UnknownUserInstance;
Profile = new(Name, FirstName, NickName); Profile = new(Name, FirstName, NickName);
InitialHP = GameplayEquilibriumConstant.InitialHP;
InitialMP = GameplayEquilibriumConstant.InitialMP;
InitialATK = GameplayEquilibriumConstant.InitialATK;
InitialDEF = GameplayEquilibriumConstant.InitialDEF;
EquipSlot = new(); EquipSlot = new();
MDF = new(); MDF = new();
NormalAttack = new(this); NormalAttack = new(this);
@ -1136,10 +1140,10 @@ namespace Milimoe.FunGame.Core.Entity
{ {
break; break;
} }
if (General.GameplayEquilibriumConstant.UseLevelBreak && checkLevelBreak) if (GameplayEquilibriumConstant.UseLevelBreak && checkLevelBreak)
{ {
// 检查角色突破进度 // 检查角色突破进度
int[] breaks = [.. General.GameplayEquilibriumConstant.LevelBreakList]; int[] breaks = [.. GameplayEquilibriumConstant.LevelBreakList];
int nextBreak = LevelBreak + 1; int nextBreak = LevelBreak + 1;
if (nextBreak < breaks.Length && Level >= breaks[nextBreak]) if (nextBreak < breaks.Length && Level >= breaks[nextBreak])
{ {
@ -1147,7 +1151,7 @@ namespace Milimoe.FunGame.Core.Entity
break; break;
} }
} }
if (Level > 0 && Level < General.GameplayEquilibriumConstant.MaxLevel && General.GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) && EXP >= need) if (Level > 0 && Level < GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) && EXP >= need)
{ {
EXP -= need; EXP -= need;
Level++; Level++;
@ -1166,10 +1170,10 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary> /// </summary>
public void OnLevelBreak() public void OnLevelBreak()
{ {
if (General.GameplayEquilibriumConstant.UseLevelBreak) if (GameplayEquilibriumConstant.UseLevelBreak)
{ {
// 检查角色突破进度 // 检查角色突破进度
int[] levels = [.. General.GameplayEquilibriumConstant.LevelBreakList]; int[] levels = [.. GameplayEquilibriumConstant.LevelBreakList];
while (LevelBreak + 1 < levels.Length && Level >= levels[LevelBreak + 1]) while (LevelBreak + 1 < levels.Length && Level >= levels[LevelBreak + 1])
{ {
LevelBreak++; LevelBreak++;
@ -1313,14 +1317,14 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
if (showEXP) if (showEXP)
{ {
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {General.GameplayEquilibriumConstant.LevelBreakList.Count}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count}");
builder.AppendLine($"经验值:{EXP}{(Level != General.GameplayEquilibriumConstant.MaxLevel && General.GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}"); builder.AppendLine($"经验值:{EXP}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
} }
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : "")); builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
builder.AppendLine($"能量值:{EP:0.##} / {General.GameplayEquilibriumConstant.MaxEP:0.##}"); builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
double exATK = ExATK + ExATK2 + ExATK3; double exATK = ExATK + ExATK2 + ExATK3;
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;
@ -1329,7 +1333,7 @@ namespace Milimoe.FunGame.Core.Entity
MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100; MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100;
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)"); builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)");
double exSPD = AGI * General.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)}");
double exSTR = ExSTR + ExSTR2; double exSTR = ExSTR + ExSTR2;
@ -1338,8 +1342,8 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"{(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv" : "")); builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"{(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv" : ""));
double exINT = ExINT + ExINT2; double exINT = ExINT + ExINT2;
builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : "")); builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : ""));
builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
builder.AppendLine($"暴击率:{CritRate * 100:0.##}%"); builder.AppendLine($"暴击率:{CritRate * 100:0.##}%");
builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%"); builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%");
builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%"); builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%");
@ -1347,8 +1351,8 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"加速系数:{AccelerationCoefficient * 100:0.##}%"); builder.AppendLine($"加速系数:{AccelerationCoefficient * 100:0.##}%");
builder.AppendLine($"物理穿透:{PhysicalPenetration * 100:0.##}%"); builder.AppendLine($"物理穿透:{PhysicalPenetration * 100:0.##}%");
builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%"); builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%");
builder.AppendLine($"魔法消耗减少:{INT * General.GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%"); builder.AppendLine($"魔法消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%");
builder.AppendLine($"能量消耗减少:{INT * General.GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%"); builder.AppendLine($"能量消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%");
if (CharacterState != CharacterState.Actionable) if (CharacterState != CharacterState.Actionable)
{ {
@ -1444,14 +1448,14 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
if (showEXP) if (showEXP)
{ {
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {General.GameplayEquilibriumConstant.LevelBreakList.Count}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count}");
builder.AppendLine($"经验值:{EXP}{(Level != General.GameplayEquilibriumConstant.MaxLevel && General.GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}"); builder.AppendLine($"经验值:{EXP}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
} }
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : "")); builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
builder.AppendLine($"能量值:{EP:0.##} / {General.GameplayEquilibriumConstant.MaxEP:0.##}"); builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
double exATK = ExATK + ExATK2 + ExATK3; double exATK = ExATK + ExATK2 + ExATK3;
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;
@ -1466,7 +1470,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
else else
{ {
double exSPD = AGI * General.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)}");
double exSTR = ExSTR + ExSTR2; double exSTR = ExSTR + ExSTR2;
@ -1476,8 +1480,8 @@ namespace Milimoe.FunGame.Core.Entity
double exINT = ExINT + ExINT2; double exINT = ExINT + ExINT2;
builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : "")); builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : ""));
} }
builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
if (!showBasicOnly) if (!showBasicOnly)
{ {
@ -1557,7 +1561,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : "")); builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
builder.AppendLine($"能量值:{EP:0.##} / {General.GameplayEquilibriumConstant.MaxEP:0.##}"); builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
double exATK = ExATK + ExATK2 + ExATK3; double exATK = ExATK + ExATK2 + ExATK3;
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.##}]" : ""));
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : "")); builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : ""));
@ -1605,7 +1609,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : "")); builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
builder.AppendLine($"能量值:{EP:0.##} / {General.GameplayEquilibriumConstant.MaxEP:0.##}"); builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
double exATK = ExATK + ExATK2 + ExATK3; double exATK = ExATK + ExATK2 + ExATK3;
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.##}]" : ""));
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : "")); builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}" + (ExPrimaryAttributeValue != 0 ? $" [{BasePrimaryAttributeValue:0.##} {(ExPrimaryAttributeValue >= 0 ? "+" : "-")} {Math.Abs(ExPrimaryAttributeValue):0.##}]" : ""));
@ -1680,14 +1684,14 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
if (showEXP) if (showEXP)
{ {
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {General.GameplayEquilibriumConstant.LevelBreakList.Count}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count}");
builder.AppendLine($"经验值:{EXP}{(Level != General.GameplayEquilibriumConstant.MaxLevel && General.GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}"); builder.AppendLine($"经验值:{EXP}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
} }
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : "")); builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
builder.AppendLine($"能量值:{EP:0.##} / {General.GameplayEquilibriumConstant.MaxEP:0.##}"); builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
double exATK = ExATK + ExATK2 + ExATK3; double exATK = ExATK + ExATK2 + ExATK3;
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;
@ -1696,7 +1700,7 @@ namespace Milimoe.FunGame.Core.Entity
MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100; MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100;
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)"); builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)");
double exSPD = AGI * General.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)}");
double exSTR = ExSTR + ExSTR2; double exSTR = ExSTR + ExSTR2;
@ -1705,8 +1709,8 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"{(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv" : "")); builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"{(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv" : ""));
double exINT = ExINT + ExINT2; double exINT = ExINT + ExINT2;
builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : "")); builder.AppendLine($"智力:{INT:0.##}" + (exINT != 0 ? $" [{BaseINT:0.##} {(exINT >= 0 ? "+" : "-")} {Math.Abs(exINT):0.##}]" : "") + (showGrowth ? $"{(INTGrowth >= 0 ? "+" : "-")}{Math.Abs(INTGrowth)}/Lv" : ""));
builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
builder.AppendLine($"暴击率:{CritRate * 100:0.##}%"); builder.AppendLine($"暴击率:{CritRate * 100:0.##}%");
builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%"); builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%");
builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%"); builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%");
@ -1714,8 +1718,8 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine($"加速系数:{AccelerationCoefficient * 100:0.##}%"); builder.AppendLine($"加速系数:{AccelerationCoefficient * 100:0.##}%");
builder.AppendLine($"物理穿透:{PhysicalPenetration * 100:0.##}%"); builder.AppendLine($"物理穿透:{PhysicalPenetration * 100:0.##}%");
builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%"); builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%");
builder.AppendLine($"魔法消耗减少:{INT * General.GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%"); builder.AppendLine($"魔法消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%");
builder.AppendLine($"能量消耗减少:{INT * General.GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%"); builder.AppendLine($"能量消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%");
if (EquipSlot.Any()) if (EquipSlot.Any())
{ {
@ -1915,8 +1919,8 @@ namespace Milimoe.FunGame.Core.Entity
Item? s = UnEquip(EquipSlotType.Shoes); Item? s = UnEquip(EquipSlotType.Shoes);
Item? ac1 = UnEquip(EquipSlotType.Accessory1); Item? ac1 = UnEquip(EquipSlotType.Accessory1);
Item? ac2 = UnEquip(EquipSlotType.Accessory2); Item? ac2 = UnEquip(EquipSlotType.Accessory2);
List<Skill> skills = new(Skills); List<Skill> skills = [.. Skills];
List<Item> items = new(Items); List<Item> items = [.. Items];
Character c = original.Copy(); Character c = original.Copy();
List<Effect> effects = [.. Effects]; List<Effect> effects = [.. Effects];
foreach (Effect e in effects) foreach (Effect e in effects)

View File

@ -52,7 +52,7 @@ namespace Milimoe.FunGame.Core.Entity
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}");
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
@ -65,10 +65,10 @@ namespace Milimoe.FunGame.Core.Entity
MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100; MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100;
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)"); builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)");
double exSPD = AGI * General.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($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
builder.AppendLine($"暴击率:{CritRate * 100:0.##}%"); builder.AppendLine($"暴击率:{CritRate * 100:0.##}%");
builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%"); builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%");
builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%"); builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%");
@ -177,7 +177,7 @@ namespace Milimoe.FunGame.Core.Entity
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}");
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
@ -190,10 +190,10 @@ namespace Milimoe.FunGame.Core.Entity
MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100; MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100;
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)"); builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)");
double exSPD = AGI * General.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($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
if (!showBasicOnly) if (!showBasicOnly)
{ {
@ -398,7 +398,7 @@ namespace Milimoe.FunGame.Core.Entity
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()); builder.AppendLine(showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser());
builder.AppendLine($"等级:{Level} / {General.GameplayEquilibriumConstant.MaxLevel}"); builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}");
double exHP = ExHP + ExHP2 + ExHP3; double exHP = ExHP + ExHP2 + ExHP3;
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "")); builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : ""));
double exMP = ExMP + ExMP2 + ExMP3; double exMP = ExMP + ExMP2 + ExMP3;
@ -411,10 +411,10 @@ namespace Milimoe.FunGame.Core.Entity
MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100; MDF.Bright + MDF.Shadow + MDF.Element + MDF.Fleabane + MDF.Particle) / 9) * 100;
if (Calculation.IsApproximatelyZero(mdf)) mdf = 0; if (Calculation.IsApproximatelyZero(mdf)) mdf = 0;
builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)"); builder.AppendLine($"魔法抗性:{mdf:0.##}%(平均)");
double exSPD = AGI * General.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($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * General.GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : "")); builder.AppendLine($"生命回复:{HR:0.##}" + (ExHR != 0 ? $" [{InitialHR + STR * GameplayEquilibriumConstant.STRtoHRFactor:0.##} {(ExHR >= 0 ? "+" : "-")} {Math.Abs(ExHR):0.##}]" : ""));
builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * General.GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : "")); builder.AppendLine($"魔法回复:{MR:0.##}" + (ExMR != 0 ? $" [{InitialMR + INT * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
builder.AppendLine($"暴击率:{CritRate * 100:0.##}%"); builder.AppendLine($"暴击率:{CritRate * 100:0.##}%");
builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%"); builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%");
builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%"); builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%");

View File

@ -248,7 +248,7 @@ namespace Milimoe.FunGame.Core.Entity
{ {
foreach (Skill skill in Skills.Passives) foreach (Skill skill in Skills.Passives)
{ {
List<Effect> effects = Character.Effects.Where(e => e.Skill == skill && e.Level > 0).ToList(); List<Effect> effects = [.. Character.Effects.Where(e => e.Skill == skill && e.Level > 0)];
foreach (Effect e in effects) foreach (Effect e in effects)
{ {
Character.Effects.Remove(e); Character.Effects.Remove(e);
@ -304,7 +304,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
/// <summary> /// <summary>
/// 局内使用物品触发 对某个角色使用 /// 局内使用物品触发
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool UseItem(IGamingQueue queue, Character character, List<Character> enemys, List<Character> teammates) public bool UseItem(IGamingQueue queue, Character character, List<Character> enemys, List<Character> teammates)
@ -318,13 +318,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
if (result && Skills.Active != null) if (result && Skills.Active != null)
{ {
Skill skill = Skills.Active; used = queue.UseItem(this, character, enemys, teammates);
List<Character> targets = queue.SelectTargets(character, skill, enemys, teammates, out cancel);
if (!cancel)
{
skill.OnSkillCasted(queue, character, targets);
used = true;
}
} }
if (used) if (used)
{ {
@ -448,11 +442,11 @@ namespace Milimoe.FunGame.Core.Entity
if (isShowInStore && Price > 0) if (isShowInStore && Price > 0)
{ {
builder.AppendLine($"售价:{Price} {General.GameplayEquilibriumConstant.InGameCurrency}"); builder.AppendLine($"售价:{Price} {GameplayEquilibriumConstant.InGameCurrency}");
} }
else if (Price > 0) else if (Price > 0)
{ {
builder.AppendLine($"回收价:{Price} {General.GameplayEquilibriumConstant.InGameCurrency}"); builder.AppendLine($"回收价:{Price} {GameplayEquilibriumConstant.InGameCurrency}");
} }
if (RemainUseTimes > 0) if (RemainUseTimes > 0)

View File

@ -38,7 +38,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
set set
{ {
_Level = Math.Min(Math.Max(1, value), General.GameplayEquilibriumConstant.MaxNormalAttackLevel); _Level = Math.Min(Math.Max(1, value), GameplayEquilibriumConstant.MaxNormalAttackLevel);
} }
} }
@ -63,7 +63,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="queue"></param> /// <param name="queue"></param>
/// <param name="attacker"></param> /// <param name="attacker"></param>
/// <param name="enemys"></param> /// <param name="enemys"></param>
public void Attack(IGamingQueue queue, Character attacker, params Character[] enemys) public void Attack(IGamingQueue queue, Character attacker, params IEnumerable<Character> enemys)
{ {
foreach (Character enemy in enemys) foreach (Character enemy in enemys)
{ {

View File

@ -48,7 +48,7 @@ namespace Milimoe.FunGame.Core.Entity
} }
set set
{ {
int max = SkillSet.GetSkillMaxLevel(SkillType); int max = SkillSet.GetSkillMaxLevel(SkillType, GameplayEquilibriumConstant);
_Level = Math.Min(Math.Max(0, value), max); _Level = Math.Min(Math.Max(0, value), max);
OnLevelUp(); OnLevelUp();
} }
@ -126,7 +126,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 实际魔法消耗 [ 魔法 ] /// 实际魔法消耗 [ 魔法 ]
/// </summary> /// </summary>
public double RealMPCost => Math.Max(0, MPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * General.GameplayEquilibriumConstant.INTtoCastMPReduce))); public double RealMPCost => Math.Max(0, MPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastMPReduce)));
/// <summary> /// <summary>
/// 魔法消耗 [ 魔法 ] /// 魔法消耗 [ 魔法 ]
@ -148,7 +148,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <summary> /// <summary>
/// 实际能量消耗 [ 战技 ] /// 实际能量消耗 [ 战技 ]
/// </summary> /// </summary>
public double RealEPCost => CostAllEP ? Math.Max(MinCostEP, Character?.EP ?? MinCostEP) : (IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * General.GameplayEquilibriumConstant.INTtoCastEPReduce)))); public double RealEPCost => CostAllEP ? Math.Max(MinCostEP, Character?.EP ?? MinCostEP) : (IsSuperSkill ? EPCost : Math.Max(0, EPCost * (1 - Calculation.PercentageCheck((Character?.INT ?? 0) * GameplayEquilibriumConstant.INTtoCastEPReduce))));
/// <summary> /// <summary>
/// 能量消耗 [ 战技 ] /// 能量消耗 [ 战技 ]

View File

@ -1,21 +1,22 @@
using System.Text; using System.Text;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Entity namespace Milimoe.FunGame.Core.Entity
{ {
public class Inventory public class Inventory : BaseEntity
{ {
/// <summary> /// <summary>
/// 库存 ID 与用户 ID 绑定 /// 库存 ID 与用户 ID 绑定
/// </summary> /// </summary>
public long Id => User.Id; public override long Id => User.Id;
/// <summary> /// <summary>
/// 库存的名称,默认为 “<see cref="User.Username"/>的库存”;可更改 /// 库存的名称,默认为 “<see cref="User.Username"/>的库存”;可更改
/// </summary> /// </summary>
public string Name public override string Name
{ {
get get
{ {
@ -105,8 +106,8 @@ namespace Milimoe.FunGame.Core.Entity
StringBuilder builder = new(); StringBuilder builder = new();
builder.AppendLine($"☆★☆ {Name} ☆★☆"); builder.AppendLine($"☆★☆ {Name} ☆★☆");
builder.AppendLine($"{General.GameplayEquilibriumConstant.InGameCurrency}{Credits:0.00}"); builder.AppendLine($"{GameplayEquilibriumConstant.InGameCurrency}{Credits:0.00}");
builder.AppendLine($"{General.GameplayEquilibriumConstant.InGameMaterial}{Materials:0.00}"); builder.AppendLine($"{GameplayEquilibriumConstant.InGameMaterial}{Materials:0.00}");
builder.AppendLine($"======= 角色 ======="); builder.AppendLine($"======= 角色 =======");
Character[] characters = [.. Characters]; Character[] characters = [.. Characters];
@ -143,5 +144,10 @@ namespace Milimoe.FunGame.Core.Entity
return builder.ToString(); return builder.ToString();
} }
public override bool Equals(IBaseEntity? other)
{
return other is Inventory && other.GetIdName() == GetIdName();
}
} }
} }

View File

@ -20,11 +20,11 @@ namespace Milimoe.FunGame.Core.Entity
List<string> awards = []; List<string> awards = [];
if (CreditsAward > 0) if (CreditsAward > 0)
{ {
awards.Add($"{General.GameplayEquilibriumConstant.InGameCurrency} * {CreditsAward}"); awards.Add($"{GameplayEquilibriumConstant.InGameCurrency} * {CreditsAward}");
} }
if (MaterialsAward > 0) if (MaterialsAward > 0)
{ {
awards.Add($"{General.GameplayEquilibriumConstant.InGameMaterial} * {MaterialsAward}"); awards.Add($"{GameplayEquilibriumConstant.InGameMaterial} * {MaterialsAward}");
} }
foreach (Item item in Awards) foreach (Item item in Awards)
{ {

View File

@ -62,7 +62,7 @@ namespace Milimoe.FunGame.Core.Entity
description = item.Description; description = item.Description;
} }
Goods goods = new(id, item, stock, name, description); Goods goods = new(id, item, stock, name, description);
goods.SetPrice(General.GameplayEquilibriumConstant.InGameCurrency, item.Price); goods.SetPrice(GameplayEquilibriumConstant.InGameCurrency, item.Price);
Goods.Add(id, goods); Goods.Add(id, goods);
} }
@ -97,7 +97,7 @@ namespace Milimoe.FunGame.Core.Entity
double price = 0; double price = 0;
if (Goods.TryGetValue(id, out Goods? goods) && goods != null) if (Goods.TryGetValue(id, out Goods? goods) && goods != null)
{ {
goods.GetPrice(General.GameplayEquilibriumConstant.InGameCurrency, out price); goods.GetPrice(GameplayEquilibriumConstant.InGameCurrency, out price);
} }
return price; return price;
} }

View File

@ -1,5 +1,6 @@
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Milimoe.FunGame.Core.Interface.Base namespace Milimoe.FunGame.Core.Interface.Base
{ {
@ -8,6 +9,11 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// </summary> /// </summary>
public interface IGamingQueue public interface IGamingQueue
{ {
/// <summary>
/// 使用的游戏平衡常数
/// </summary>
public EquilibriumConstant GameplayEquilibriumConstant { get; }
/// <summary> /// <summary>
/// 用于文本输出 /// 用于文本输出
/// </summary> /// </summary>
@ -124,6 +130,16 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="interrupter"></param> /// <param name="interrupter"></param>
public void InterruptCasting(Character caster, Character interrupter); public void InterruptCasting(Character caster, Character interrupter);
/// <summary>
/// 使用物品
/// </summary>
/// <param name="item"></param>
/// <param name="caster"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <returns></returns>
public bool UseItem(Item item, Character caster, List<Character> enemys, List<Character> teammates);
/// <summary> /// <summary>
/// 选取技能目标 /// 选取技能目标
/// </summary> /// </summary>
@ -131,9 +147,8 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="skill"></param> /// <param name="skill"></param>
/// <param name="enemys"></param> /// <param name="enemys"></param>
/// <param name="teammates"></param> /// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
public List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates, out bool cancel); public List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates);
/// <summary> /// <summary>
/// 选取普通攻击目标 /// 选取普通攻击目标
@ -142,8 +157,7 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="attack"></param> /// <param name="attack"></param>
/// <param name="enemys"></param> /// <param name="enemys"></param>
/// <param name="teammates"></param> /// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
public List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, out bool cancel); public List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates);
} }
} }

View File

@ -1,4 +1,7 @@
/** 
using Milimoe.FunGame.Core.Model;
/**
* String Set * String Set
*/ */
namespace Milimoe.FunGame.Core.Library.Constant namespace Milimoe.FunGame.Core.Library.Constant
@ -619,15 +622,16 @@ namespace Milimoe.FunGame.Core.Library.Constant
}; };
} }
public static int GetSkillMaxLevel(SkillType type) public static int GetSkillMaxLevel(SkillType type, EquilibriumConstant? gameplayConstant = null)
{ {
gameplayConstant ??= General.GameplayEquilibriumConstant;
return type switch return type switch
{ {
SkillType.Magic => General.GameplayEquilibriumConstant.MaxMagicLevel, SkillType.Magic => gameplayConstant.MaxMagicLevel,
SkillType.Skill => General.GameplayEquilibriumConstant.MaxSkillLevel, SkillType.Skill => gameplayConstant.MaxSkillLevel,
SkillType.SuperSkill => General.GameplayEquilibriumConstant.MaxSuperSkillLevel, SkillType.SuperSkill => gameplayConstant.MaxSuperSkillLevel,
SkillType.Item => General.GameplayEquilibriumConstant.MaxSkillLevel, SkillType.Item => gameplayConstant.MaxSkillLevel,
_ => General.GameplayEquilibriumConstant.MaxPassiveSkillLevel _ => gameplayConstant.MaxPassiveSkillLevel
}; };
} }

View File

@ -680,7 +680,8 @@ namespace Milimoe.FunGame.Core.Library.Constant
PreCastSkill, PreCastSkill,
CastSkill, CastSkill,
CastSuperSkill, CastSuperSkill,
UseItem UseItem,
EndTurn
} }
public enum VerifyCodeType public enum VerifyCodeType

View File

@ -10,6 +10,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
public class ActionQueue : IGamingQueue public class ActionQueue : IGamingQueue
{ {
/// <summary>
/// 使用的游戏平衡常数
/// </summary>
public EquilibriumConstant GameplayEquilibriumConstant { get; } = General.GameplayEquilibriumConstant;
/// <summary> /// <summary>
/// 用于文本输出 /// 用于文本输出
/// </summary> /// </summary>
@ -35,6 +40,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
public List<Team> EliminatedTeams => _eliminatedTeams; public List<Team> EliminatedTeams => _eliminatedTeams;
/// <summary>
/// 角色是否在 AI 控制下
/// </summary>
public HashSet<Character> CharactersInAI => _charactersInAI;
/// <summary> /// <summary>
/// 角色数据 /// 角色数据
/// </summary> /// </summary>
@ -113,13 +123,18 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
protected readonly List<Team> _eliminatedTeams = []; protected readonly List<Team> _eliminatedTeams = [];
/// <summary>
/// 角色是否在 AI 控制下
/// </summary>
protected readonly HashSet<Character> _charactersInAI = [];
/// <summary> /// <summary>
/// 硬直时间表 /// 硬直时间表
/// </summary> /// </summary>
protected readonly Dictionary<Character, double> _hardnessTimes = []; protected readonly Dictionary<Character, double> _hardnessTimes = [];
/// <summary> /// <summary>
/// 角色正在吟唱的魔法 /// 角色正在吟唱的技能(通常是魔法
/// </summary> /// </summary>
protected readonly Dictionary<Character, SkillTarget> _castingSkills = []; protected readonly Dictionary<Character, SkillTarget> _castingSkills = [];
@ -128,6 +143,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
protected readonly Dictionary<Character, Skill> _castingSuperSkills = []; protected readonly Dictionary<Character, Skill> _castingSuperSkills = [];
/// <summary>
/// 角色即将使用的物品
/// </summary>
protected readonly Dictionary<Character, Skill> _willUseItems = [];
/// <summary> /// <summary>
/// 角色目前赚取的金钱 /// 角色目前赚取的金钱
/// </summary> /// </summary>
@ -332,10 +352,12 @@ namespace Milimoe.FunGame.Core.Model
_cutCount.Clear(); _cutCount.Clear();
_castingSkills.Clear(); _castingSkills.Clear();
_castingSuperSkills.Clear(); _castingSuperSkills.Clear();
_willUseItems.Clear();
_maxContinuousKilling.Clear(); _maxContinuousKilling.Clear();
_continuousKilling.Clear(); _continuousKilling.Clear();
_earnedMoney.Clear(); _earnedMoney.Clear();
_eliminated.Clear(); _eliminated.Clear();
_charactersInAI.Clear();
} }
/// <summary> /// <summary>
@ -413,7 +435,7 @@ namespace Milimoe.FunGame.Core.Model
if (isCheckProtected) if (isCheckProtected)
{ {
// 查找保护条件 被插队超过此次数便能获得插队补偿 即行动保护 // 查找保护条件 被插队超过此次数便能获得插队补偿 即行动保护
int countProtected = _queue.Count; int countProtected = Math.Max(5, _queue.Count);
// 查找队列中是否有满足插队补偿条件的角色(最后一个) // 查找队列中是否有满足插队补偿条件的角色(最后一个)
var list = _queue var list = _queue
@ -564,6 +586,12 @@ namespace Milimoe.FunGame.Core.Model
List<Item> items = [.. character.Items.Where(i => i.IsActive && i.Skills.Active != null && i.Enable && i.IsInGameItem && List<Item> items = [.. character.Items.Where(i => i.IsActive && i.Skills.Active != null && i.Enable && i.IsInGameItem &&
i.Skills.Active.SkillType == SkillType.Item && i.Skills.Active.Enable && !i.Skills.Active.IsInEffect && i.Skills.Active.CurrentCD == 0 && i.Skills.Active.RealMPCost <= character.MP && i.Skills.Active.RealEPCost <= character.EP)]; i.Skills.Active.SkillType == SkillType.Item && i.Skills.Active.Enable && !i.Skills.Active.IsInEffect && i.Skills.Active.CurrentCD == 0 && i.Skills.Active.RealMPCost <= character.MP && i.Skills.Active.RealEPCost <= character.EP)];
// 回合开始事件,允许事件返回 false 接管回合操作
if (!OnTurnStart(character, enemys, teammates, skills, items))
{
return _isGameEnd;
}
// 此变量用于在取消选择时,能够重新行动 // 此变量用于在取消选择时,能够重新行动
bool decided = false; bool decided = false;
// 最大取消次数 // 最大取消次数
@ -714,10 +742,15 @@ namespace Milimoe.FunGame.Core.Model
if (type == CharacterActionType.NormalAttack) if (type == CharacterActionType.NormalAttack)
{ {
// 使用普通攻击逻辑 // 使用普通攻击逻辑
Character[] targets = [.. SelectTargets(character, character.NormalAttack, enemys, teammates, out bool cancel)]; List<Character> targets = SelectTargets(character, character.NormalAttack, enemys, teammates);
LastRound.Targets = [.. targets]; if (targets.Count == 0 && _charactersInAI.Contains(character) && enemys.Count > 0)
if (!cancel)
{ {
// 如果没有选取目标,且角色在 AI 控制下,则随机选取一个目标
targets = [enemys[Random.Shared.Next(enemys.Count)]];
}
if (targets.Count > 0)
{
LastRound.Targets = [.. targets];
decided = true; decided = true;
character.NormalAttack.Attack(this, character, targets); character.NormalAttack.Attack(this, character, targets);
baseTime = character.NormalAttack.HardnessTime; baseTime = character.NormalAttack.HardnessTime;
@ -731,14 +764,25 @@ namespace Milimoe.FunGame.Core.Model
else if (type == CharacterActionType.PreCastSkill) else if (type == CharacterActionType.PreCastSkill)
{ {
// 预使用技能,即开始吟唱逻辑 // 预使用技能,即开始吟唱逻辑
Skill? skill = OnSelectSkill(character, skills);
if (_charactersInAI.Contains(character))
{
skill = skills[Random.Shared.Next(skills.Count)];
}
if (skill != null)
{
// 吟唱前需要先选取目标 // 吟唱前需要先选取目标
Skill skill = skills[Random.Shared.Next(skills.Count)];
if (skill.SkillType == SkillType.Magic) if (skill.SkillType == SkillType.Magic)
{ {
List<Character> targets = SelectTargets(character, skill, enemys, teammates, out bool cancel); List<Character> targets = SelectTargets(character, skill, enemys, teammates);
LastRound.Targets = [.. targets]; if (targets.Count == 0 && _charactersInAI.Contains(character) && enemys.Count > 0)
if (!cancel)
{ {
// 如果没有选取目标,且角色在 AI 控制下,则随机选取一个目标
targets = [enemys[Random.Shared.Next(enemys.Count)]];
}
if (targets.Count > 0)
{
LastRound.Targets = [.. targets];
decided = true; decided = true;
character.CharacterState = CharacterState.Casting; character.CharacterState = CharacterState.Casting;
_castingSkills.Add(character, new(skill, targets)); _castingSkills.Add(character, new(skill, targets));
@ -748,12 +792,18 @@ namespace Milimoe.FunGame.Core.Model
} }
else else
{ {
// 只有魔法需要吟唱,战技和爆发技直接释放
if (CheckCanCast(character, skill, out double cost)) if (CheckCanCast(character, skill, out double cost))
{ {
List<Character> targets = SelectTargets(character, skill, enemys, teammates, out bool cancel); List<Character> targets = SelectTargets(character, skill, enemys, teammates);
LastRound.Targets = [.. targets]; if (targets.Count == 0 && _charactersInAI.Contains(character) && enemys.Count > 0)
if (!cancel)
{ {
// 如果没有选取目标,且角色在 AI 控制下,则随机选取一个目标
targets = [enemys[Random.Shared.Next(enemys.Count)]];
}
if (targets.Count > 0)
{
LastRound.Targets = [.. targets];
decided = true; decided = true;
skill.OnSkillCasting(this, character, targets); skill.OnSkillCasting(this, character, targets);
skill.BeforeSkillCasted(); skill.BeforeSkillCasted();
@ -776,6 +826,7 @@ namespace Milimoe.FunGame.Core.Model
} }
LastRound.Skill = skill; LastRound.Skill = skill;
} }
}
else if (type == CharacterActionType.CastSkill) else if (type == CharacterActionType.CastSkill)
{ {
decided = true; decided = true;
@ -828,7 +879,7 @@ namespace Milimoe.FunGame.Core.Model
if (CheckCanCast(character, skill, out double cost)) if (CheckCanCast(character, skill, out double cost))
{ {
// 预释放的爆发技不可取消 // 预释放的爆发技不可取消
List<Character> targets = SelectTargets(character, skill, enemys, teammates, out _); List<Character> targets = SelectTargets(character, skill, enemys, teammates);
LastRound.Targets = [.. targets]; LastRound.Targets = [.. targets];
skill.BeforeSkillCasted(); skill.BeforeSkillCasted();
@ -858,6 +909,22 @@ namespace Milimoe.FunGame.Core.Model
else if (type == CharacterActionType.UseItem) else if (type == CharacterActionType.UseItem)
{ {
// 使用物品逻辑 // 使用物品逻辑
Item? item = OnSelectItem(character, items);
if (item != null && item.Skills.Active != null)
{
Skill skill = item.Skills.Active;
if (UseItem(item, character, enemys, teammates))
{
decided = true;
LastRound.Item = item;
baseTime = skill.HardnessTime;
effects = [.. character.Effects.Where(e => e.Level > 0)];
foreach (Effect effect in effects)
{
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
}
}
}
} }
} }
@ -881,20 +948,17 @@ namespace Milimoe.FunGame.Core.Model
if (character.CharacterState != CharacterState.Casting) if (character.CharacterState != CharacterState.Casting)
{ {
newHardnessTime = Math.Max(0, Calculation.Round2Digits(baseTime * (1 - character.ActionCoefficient))); newHardnessTime = Math.Max(0, Calculation.Round2Digits(baseTime * (1 - character.ActionCoefficient)));
WriteLine("[ " + character + " ] 回合结束,获得硬直时间: " + newHardnessTime); WriteLine($"[ {character} ] 回合结束,获得硬直时间:{newHardnessTime} {GameplayEquilibriumConstant.InGameTime}");
} }
else else
{ {
newHardnessTime = Math.Max(0, Calculation.Round2Digits(baseTime * (1 - character.AccelerationCoefficient))); newHardnessTime = Math.Max(0, Calculation.Round2Digits(baseTime * (1 - character.AccelerationCoefficient)));
WriteLine("[ " + character + " ] 进行吟唱,持续时间: " + newHardnessTime); WriteLine($"[ {character} ] 进行吟唱,持续时间:{newHardnessTime} {GameplayEquilibriumConstant.InGameTime}");
LastRound.CastTime = newHardnessTime; LastRound.CastTime = newHardnessTime;
} }
AddCharacter(character, newHardnessTime, isCheckProtected); AddCharacter(character, newHardnessTime, isCheckProtected);
LastRound.HardnessTime = newHardnessTime; LastRound.HardnessTime = newHardnessTime;
// 有人想要插队吗?
WillPreCastSuperSkill(character);
effects = [.. character.Effects.Where(e => e.Level > 0)]; effects = [.. character.Effects.Where(e => e.Level > 0)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
@ -920,6 +984,12 @@ namespace Milimoe.FunGame.Core.Model
} }
} }
// 有人想要插队吗?
WillPreCastSuperSkill(character);
// 回合结束事件
OnTurnEnd(character);
AfterTurn(character); AfterTurn(character);
WriteLine(""); WriteLine("");
@ -966,7 +1036,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
double hardnessTime = 5; double hardnessTime = 5;
character.Respawn(_original[character.Guid]); character.Respawn(_original[character.Guid]);
WriteLine($"[ {character} ] 已复活!获得 {hardnessTime} 硬直时间。"); WriteLine($"[ {character} ] 已复活!获得 {hardnessTime} {GameplayEquilibriumConstant.InGameTime}的硬直时间。");
AddCharacter(character, hardnessTime, false); AddCharacter(character, hardnessTime, false);
LastRound.Respawns.Add(character); LastRound.Respawns.Add(character);
_respawnCountdown.Remove(character); _respawnCountdown.Remove(character);
@ -1119,14 +1189,14 @@ namespace Milimoe.FunGame.Core.Model
_assistDamage[actor][enemy] += damage; _assistDamage[actor][enemy] += damage;
// 造成伤害和受伤都可以获得能量 // 造成伤害和受伤都可以获得能量
double ep = GetEP(damage, 0.03, 30); double ep = GetEP(damage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax);
effects = [.. actor.Effects]; effects = [.. actor.Effects];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
effect.AlterEPAfterDamage(actor, ref ep); effect.AlterEPAfterDamage(actor, ref ep);
} }
actor.EP += ep; actor.EP += ep;
ep = GetEP(damage, 0.015, 15); ep = GetEP(damage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax);
effects = [.. enemy.Effects.Where(e => e.Level > 0)]; effects = [.. enemy.Effects.Where(e => e.Level > 0)];
foreach (Effect effect in effects) foreach (Effect effect in effects)
{ {
@ -1276,7 +1346,7 @@ namespace Milimoe.FunGame.Core.Model
double penetratedDEF = (1 - actor.PhysicalPenetration) * enemy.DEF; double penetratedDEF = (1 - actor.PhysicalPenetration) * enemy.DEF;
// 物理伤害减免 // 物理伤害减免
double physicalDamageReduction = penetratedDEF / (penetratedDEF + General.GameplayEquilibriumConstant.DEFReductionFactor); double physicalDamageReduction = penetratedDEF / (penetratedDEF + GameplayEquilibriumConstant.DEFReductionFactor);
// 最终的物理伤害 // 最终的物理伤害
finalDamage = expectedDamage * (1 - Calculation.PercentageCheck(physicalDamageReduction + enemy.ExPDR)); finalDamage = expectedDamage * (1 - Calculation.PercentageCheck(physicalDamageReduction + enemy.ExPDR));
@ -1551,7 +1621,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
money += (coefficient + 1) * Random.Shared.Next(50, 100); money += (coefficient + 1) * Random.Shared.Next(50, 100);
string termination = CharacterSet.GetContinuousKilling(coefficient); string termination = CharacterSet.GetContinuousKilling(coefficient);
string msg = $"[ {killer} ] 终结了 [ {death} ]{(termination != "" ? " " + termination : "")},获得 {money} {General.GameplayEquilibriumConstant.InGameCurrency}"; string msg = $"[ {killer} ] 终结了 [ {death} ]{(termination != "" ? " " + termination : "")},获得 {money} {GameplayEquilibriumConstant.InGameCurrency}";
LastRound.DeathContinuousKilling.Add(msg); LastRound.DeathContinuousKilling.Add(msg);
if (assists.Length > 1) if (assists.Length > 1)
{ {
@ -1561,7 +1631,7 @@ namespace Milimoe.FunGame.Core.Model
} }
else else
{ {
string msg = $"[ {killer} ] 杀死了 [ {death} ],获得 {money} {General.GameplayEquilibriumConstant.InGameCurrency}"; string msg = $"[ {killer} ] 杀死了 [ {death} ],获得 {money} {GameplayEquilibriumConstant.InGameCurrency}";
LastRound.DeathContinuousKilling.Add(msg); LastRound.DeathContinuousKilling.Add(msg);
if (assists.Length > 1) if (assists.Length > 1)
{ {
@ -1576,7 +1646,7 @@ namespace Milimoe.FunGame.Core.Model
_stats[killer].FirstKills += 1; _stats[killer].FirstKills += 1;
_stats[death].FirstDeaths += 1; _stats[death].FirstDeaths += 1;
money += 200; money += 200;
WriteLine($"[ {killer} ] 拿下了第一滴血!额外奖励 200 {General.GameplayEquilibriumConstant.InGameCurrency}"); WriteLine($"[ {killer} ] 拿下了第一滴血!额外奖励 200 {GameplayEquilibriumConstant.InGameCurrency}");
} }
int kills = _continuousKilling[killer]; int kills = _continuousKilling[killer];
@ -1640,7 +1710,7 @@ namespace Milimoe.FunGame.Core.Model
double respawnTime = Calculation.Round2Digits(Math.Min(90, death.Level * 0.15 + times * 2.77 + coefficient * Random.Shared.Next(1, 3))); double respawnTime = Calculation.Round2Digits(Math.Min(90, death.Level * 0.15 + times * 2.77 + coefficient * Random.Shared.Next(1, 3)));
_respawnCountdown.TryAdd(death, respawnTime); _respawnCountdown.TryAdd(death, respawnTime);
LastRound.RespawnCountdowns.TryAdd(death, respawnTime); LastRound.RespawnCountdowns.TryAdd(death, respawnTime);
WriteLine($"[ {death} ] 进入复活倒计时:{respawnTime:0.##} 时间"); WriteLine($"[ {death} ] 进入复活倒计时:{respawnTime:0.##} {GameplayEquilibriumConstant.InGameTime}");
} }
// 移除死者的施法 // 移除死者的施法
@ -1659,7 +1729,7 @@ namespace Milimoe.FunGame.Core.Model
{ {
caster.CharacterState = CharacterState.Actionable; caster.CharacterState = CharacterState.Actionable;
} }
WriteLine($"[ {caster} ] 终止了 [ {st.Skill.Name} ] 的施法" + (_hardnessTimes[caster] > 3 ? ",并获得了 3 硬直时间的补偿。" : "。")); WriteLine($"[ {caster} ] 终止了 [ {st.Skill.Name} ] 的施法" + (_hardnessTimes[caster] > 3 ? $",并获得了 3 {GameplayEquilibriumConstant.InGameTime}的硬直时间的补偿。" : "。"));
if (_hardnessTimes[caster] > 3) if (_hardnessTimes[caster] > 3)
{ {
_hardnessTimes[caster] = 3; _hardnessTimes[caster] = 3;
@ -1686,7 +1756,7 @@ namespace Milimoe.FunGame.Core.Model
string topCharacter = ec.ToString() + string topCharacter = ec.ToString() +
(statistics.FirstKills > 0 ? " [ 第一滴血 ]" : "") + (statistics.FirstKills > 0 ? " [ 第一滴血 ]" : "") +
(_maxContinuousKilling.TryGetValue(ec, out int kills) && kills > 1 ? $" [ {CharacterSet.GetContinuousKilling(kills)} ]" : "") + (_maxContinuousKilling.TryGetValue(ec, out int kills) && kills > 1 ? $" [ {CharacterSet.GetContinuousKilling(kills)} ]" : "") +
(_earnedMoney.TryGetValue(ec, out int earned) ? $" [ 已赚取 {earned} {General.GameplayEquilibriumConstant.InGameCurrency} ]" : ""); (_earnedMoney.TryGetValue(ec, out int earned) ? $" [ 已赚取 {earned} {GameplayEquilibriumConstant.InGameCurrency} ]" : "");
if (top == 1) if (top == 1)
{ {
WriteLine("冠军:" + topCharacter); WriteLine("冠军:" + topCharacter);
@ -1762,13 +1832,13 @@ namespace Milimoe.FunGame.Core.Model
string respawning = ""; string respawning = "";
if (ec.HP <= 0) if (ec.HP <= 0)
{ {
respawning = "[ " + (_respawnCountdown.TryGetValue(ec, out double time) && time > 0 ? $"{time:0.##} 时间后复活" : "阵亡") + " ] "; respawning = "[ " + (_respawnCountdown.TryGetValue(ec, out double time) && time > 0 ? $"{time:0.##} {GameplayEquilibriumConstant.InGameTime}后复活" : "阵亡") + " ] ";
} }
string topCharacter = respawning + ec.ToString() + string topCharacter = respawning + ec.ToString() +
(statistics.FirstKills > 0 ? " [ 第一滴血 ]" : "") + (statistics.FirstKills > 0 ? " [ 第一滴血 ]" : "") +
(_maxContinuousKilling.TryGetValue(ec, out int kills) && kills > 1 ? $" [ {CharacterSet.GetContinuousKilling(kills)} ]" : "") + (_maxContinuousKilling.TryGetValue(ec, out int kills) && kills > 1 ? $" [ {CharacterSet.GetContinuousKilling(kills)} ]" : "") +
(_earnedMoney.TryGetValue(ec, out int earned) ? $" [ 已赚取 {earned} {General.GameplayEquilibriumConstant.InGameCurrency} ]" : "") + (_earnedMoney.TryGetValue(ec, out int earned) ? $" [ 已赚取 {earned} {GameplayEquilibriumConstant.InGameCurrency} ]" : "") +
$"{statistics.Kills} / {statistics.Assists}{(MaxRespawnTimes != 0 ? " / " + statistics.Deaths : "")}"; $"{statistics.Kills} / {statistics.Assists}{(MaxRespawnTimes != 0 ? " / " + statistics.Deaths : "")}";
topTeam += topCharacter + "\r\n"; topTeam += topCharacter + "\r\n";
if (top == 1) if (top == 1)
@ -1838,14 +1908,55 @@ namespace Milimoe.FunGame.Core.Model
} }
/// <summary> /// <summary>
/// 是否在回合外释放爆发技插队 /// 检查是否可以释放技能(物品版)
/// </summary>
/// <param name="caster"></param>
/// <param name="item"></param>
/// <param name="costMP"></param>
/// <param name="costEP"></param>
/// <returns></returns>
public bool CheckCanCast(Character caster, Item item, out double costMP, out double costEP)
{
Skill? skill = item.Skills.Active;
if (skill is null)
{
costMP = 0;
costEP = 0;
return false;
}
costMP = skill.RealMPCost;
costEP = skill.RealEPCost;
bool isMPOk = false;
bool isEPOk = false;
if (costMP > 0 && costMP <= caster.MP)
{
isMPOk = true;
}
else
{
WriteLine("[ " + caster + $" ] 魔法不足!");
}
costEP = skill.RealEPCost;
if (costEP > 0 && costEP <= caster.EP)
{
isEPOk = true;
}
else
{
WriteLine("[ " + caster + $" ] 能量不足!");
}
return isMPOk && isEPOk;
}
/// <summary>
/// 是否在回合外释放爆发技插队(仅自动化)
/// </summary> /// </summary>
/// <param name="character">当前正在行动的角色</param> /// <param name="character">当前正在行动的角色</param>
/// <returns></returns> /// <returns></returns>
public void WillPreCastSuperSkill(Character character) public void WillPreCastSuperSkill(Character character)
{ {
// 选取在顺序表一半之后的角色 // 选取除了回合内角色之外的 AI 控制角色
foreach (Character other in _queue.Where(c => c != character && c.CharacterState == CharacterState.Actionable && _queue.IndexOf(c) >= _queue.Count / 2).ToList()) foreach (Character other in _queue.Where(c => c != character && c.CharacterState == CharacterState.Actionable && _charactersInAI.Contains(c)).ToList())
{ {
// 有 65% 欲望插队 // 有 65% 欲望插队
if (Random.Shared.NextDouble() < 0.65) if (Random.Shared.NextDouble() < 0.65)
@ -1854,20 +1965,7 @@ namespace Milimoe.FunGame.Core.Model
if (skills.Count > 0) if (skills.Count > 0)
{ {
Skill skill = skills[Random.Shared.Next(skills.Count)]; Skill skill = skills[Random.Shared.Next(skills.Count)];
_castingSuperSkills.Add(other, skill); SetCharacterPreCastSuperSkill(other, skill);
other.CharacterState = CharacterState.PreCastSuperSkill;
_queue.Remove(other);
_cutCount.Remove(character);
AddCharacter(other, 0, false);
WriteLine("[ " + other + " ] 预释放了爆发技!!");
foreach (Character c in _hardnessTimes.Keys)
{
if (_hardnessTimes[c] != 0)
{
_hardnessTimes[c] = Calculation.Round2Digits(_hardnessTimes[c] + 0.01);
}
}
skill.OnSkillCasting(this, other, []);
} }
} }
} }
@ -2030,6 +2128,94 @@ namespace Milimoe.FunGame.Core.Model
return item; return item;
} }
/// <summary>
/// 使用物品实际逻辑
/// </summary>
/// <param name="item"></param>
/// <param name="character"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <returns></returns>
public bool UseItem(Item item, Character character, List<Character> enemys, List<Character> teammates)
{
Skill? skill = item.Skills.Active;
if (skill != null)
{
if (CheckCanCast(character, skill, out double cost))
{
List<Character> targets = SelectTargets(character, skill, enemys, teammates);
if (targets.Count == 0 && _charactersInAI.Contains(character) && enemys.Count > 0)
{
// 如果没有选取目标,且角色在 AI 控制下,则随机选取一个目标
targets = [enemys[Random.Shared.Next(enemys.Count)]];
}
if (targets.Count > 0)
{
LastRound.Targets = [.. targets];
skill.OnSkillCasting(this, character, targets);
skill.BeforeSkillCasted();
character.EP -= cost;
skill.CurrentCD = skill.RealCD;
skill.Enable = false;
LastRound.SkillCost = $"{-cost:0.##} EP";
WriteLine("[ " + character + $" ] 消耗了 {cost:0.##} 点能量,释放了{(skill.IsSuperSkill ? "" : "")} [ {skill.Name} ]{(skill.Slogan != "" ? skill.Slogan : "")}");
skill.OnSkillCasted(this, character, targets);
return true;
}
}
}
return false;
}
/// <summary>
/// 设置角色将预释放爆发技
/// </summary>
/// <param name="character"></param>
/// <param name="skill"></param>
public void SetCharacterPreCastSuperSkill(Character character, Skill skill)
{
if (character.CharacterState == CharacterState.Actionable)
{
_castingSuperSkills.Add(character, skill);
character.CharacterState = CharacterState.PreCastSuperSkill;
_queue.Remove(character);
_cutCount.Remove(character);
AddCharacter(character, 0, false);
WriteLine("[ " + character + " ] 预释放了爆发技!!");
foreach (Character c in _hardnessTimes.Keys)
{
if (_hardnessTimes[c] != 0)
{
_hardnessTimes[c] = Calculation.Round2Digits(_hardnessTimes[c] + 0.01);
}
}
skill.OnSkillCasting(this, character, []);
}
}
/// <summary>
/// 设置角色为 AI 控制
/// </summary>
/// <param name="cancel"></param>
/// <param name="characters"></param>
public void SetCharactersToAIControl(bool cancel = false, params IEnumerable<Character> characters)
{
foreach (Character character in characters)
{
if (cancel)
{
_charactersInAI.Remove(character);
}
else
{
_charactersInAI.Add(character);
}
}
}
/// <summary> /// <summary>
/// 选取技能目标 /// 选取技能目标
/// </summary> /// </summary>
@ -2037,16 +2223,14 @@ namespace Milimoe.FunGame.Core.Model
/// <param name="skill"></param> /// <param name="skill"></param>
/// <param name="enemys"></param> /// <param name="enemys"></param>
/// <param name="teammates"></param> /// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
public virtual List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates, out bool cancel) public virtual List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates)
{ {
List<Character> targets = OnSelectSkillTargets(caster, skill, enemys, teammates); List<Character> targets = OnSelectSkillTargets(caster, skill, enemys, teammates);
if (targets.Count == 0) if (targets.Count == 0)
{ {
targets = skill.SelectTargets(caster, enemys, teammates); targets = skill.SelectTargets(caster, enemys, teammates);
} }
cancel = targets.Count == 0;
return targets; return targets;
} }
@ -2057,16 +2241,10 @@ namespace Milimoe.FunGame.Core.Model
/// <param name="attack"></param> /// <param name="attack"></param>
/// <param name="enemys"></param> /// <param name="enemys"></param>
/// <param name="teammates"></param> /// <param name="teammates"></param>
/// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
public virtual List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, out bool cancel) public virtual List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates)
{ {
List<Character> targets = OnSelectNormalAttackTargets(character, attack, enemys, teammates); List<Character> targets = OnSelectNormalAttackTargets(character, attack, enemys, teammates);
if (targets.Count == 0 && enemys.Count > 0)
{
targets = [enemys[Random.Shared.Next(enemys.Count)]];
}
cancel = targets.Count == 0;
return targets; return targets;
} }
@ -2085,6 +2263,32 @@ namespace Milimoe.FunGame.Core.Model
return DecideAction?.Invoke(character, pUseItem, pCastSkill, pNormalAttack) ?? CharacterActionType.None; return DecideAction?.Invoke(character, pUseItem, pCastSkill, pNormalAttack) ?? CharacterActionType.None;
} }
public delegate Skill SelectSkillEventHandler(Character character, List<Skill> skills);
public event SelectSkillEventHandler? SelectSkill;
/// <summary>
/// 角色需要选择一个技能
/// </summary>
/// <param name="character"></param>
/// <param name="skills"></param>
/// <returns></returns>
public Skill? OnSelectSkill(Character character, List<Skill> skills)
{
return SelectSkill?.Invoke(character, skills);
}
public delegate Item SelectItemEventHandler(Character character, List<Item> items);
public event SelectItemEventHandler? SelectItem;
/// <summary>
/// 角色需要选择一个物品
/// </summary>
/// <param name="character"></param>
/// <param name="items"></param>
/// <returns></returns>
public Item? OnSelectItem(Character character, List<Item> items)
{
return SelectItem?.Invoke(character, items);
}
public delegate List<Character> SelectSkillTargetsEventHandler(Character caster, Skill skill, List<Character> enemys, List<Character> teammates); public delegate List<Character> SelectSkillTargetsEventHandler(Character caster, Skill skill, List<Character> enemys, List<Character> teammates);
public event SelectSkillTargetsEventHandler? SelectSkillTargets; public event SelectSkillTargetsEventHandler? SelectSkillTargets;
/// <summary> /// <summary>
@ -2114,5 +2318,33 @@ namespace Milimoe.FunGame.Core.Model
{ {
return SelectNormalAttackTargets?.Invoke(character, attack, enemys, teammates) ?? []; return SelectNormalAttackTargets?.Invoke(character, attack, enemys, teammates) ?? [];
} }
public delegate bool TurnStartEventHandler(Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items);
public event TurnStartEventHandler? TurnStart;
/// <summary>
/// 回合开始事件
/// </summary>
/// <param name="character"></param>
/// <param name="enemys"></param>
/// <param name="teammates"></param>
/// <param name="skills"></param>
/// <param name="items"></param>
/// <returns></returns>
public bool OnTurnStart(Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{
return TurnStart?.Invoke(character, enemys, teammates, skills, items) ?? true;
}
public delegate void TurnEndEventHandler(Character character);
public event TurnEndEventHandler? TurnEnd;
/// <summary>
/// 回合结束事件
/// </summary>
/// <param name="character"></param>
/// <returns></returns>
public void OnTurnEnd(Character character)
{
TurnEnd?.Invoke(character);
}
} }
} }

View File

@ -1,3 +1,5 @@
using Milimoe.FunGame.Core.Entity;
namespace Milimoe.FunGame.Core.Model namespace Milimoe.FunGame.Core.Model
{ {
/// <summary> /// <summary>
@ -15,6 +17,11 @@ namespace Milimoe.FunGame.Core.Model
/// </summary> /// </summary>
public string InGameMaterial { get; set; } = "材料"; public string InGameMaterial { get; set; } = "材料";
/// <summary>
/// 游戏时间名称(如技能冷却、硬直)
/// </summary>
public string InGameTime { get; set; } = "时间";
/// <summary> /// <summary>
/// 晋升点数上限 /// 晋升点数上限
/// </summary> /// </summary>
@ -258,5 +265,37 @@ namespace Milimoe.FunGame.Core.Model
/// 每 1 点敏捷增加闪避率 /// 每 1 点敏捷增加闪避率
/// </summary> /// </summary>
public double AGItoEvadeRateMultiplier { get; set; } = 0.00175; public double AGItoEvadeRateMultiplier { get; set; } = 0.00175;
/// <summary>
/// 造成伤害获得能量值因子
/// </summary>
public double DamageGetEPFactor { get; set; } = 0.03;
/// <summary>
/// 造成伤害获得能量值上限
/// </summary>
public double DamageGetEPMax { get; set; } = 30;
/// <summary>
/// 受到伤害获得能量值因子
/// </summary>
public double TakenDamageGetEPFactor { get; set; } = 0.015;
/// <summary>
/// 受到伤害获得能量值上限
/// </summary>
public double TakenDamageGetEPMax { get; set; } = 15;
/// <summary>
/// 应用此游戏平衡常数给实体
/// </summary>
/// <param name="entities"></param>
public void SetEquilibriumConstant(params BaseEntity[] entities)
{
foreach (BaseEntity entity in entities)
{
entity.GameplayEquilibriumConstant = this;
}
}
} }
} }