diff --git a/OshimaModules/Skills/CHAOS/雇佣兵团.cs b/OshimaModules/Skills/CHAOS/雇佣兵团.cs index 3e1f222..afdb0c2 100644 --- a/OshimaModules/Skills/CHAOS/雇佣兵团.cs +++ b/OshimaModules/Skills/CHAOS/雇佣兵团.cs @@ -28,7 +28,7 @@ namespace Oshima.FunGame.OshimaModules.Skills public override string Name => Skill.Name; public override string Description => $"{Skill.SkillOwner()}在场上时,会召唤数名雇佣兵协助战斗,初始数量为 {最小数量} 名,雇佣兵具有独立的回合,生命值为{Skill.SkillOwner()}的 {生命值比例 * 100:0.##}% [ {Skill.Character?.MaxHP * 生命值比例:0.##} ],攻击力为{Skill.SkillOwner()}的 {攻击力比例 * 100:0.##}% 基础攻击力 [ {Skill.Character?.BaseATK * 攻击力比例:0.##} ]," + $"完整继承其他能力值(暴击率、闪避率等),雇佣兵每{GameplayEquilibriumConstant.InGameTime}流失 {生命流失 * 100:0.##}% 当前生命值。当{Skill.SkillOwner()}参与击杀时,便会临时产生一名额外的雇佣兵。场上最多可以存在 {最大数量} 名雇佣兵,达到数量后不再产生新的雇佣兵;当不足 {最小数量} 名雇佣兵时,{补充间隔} {GameplayEquilibriumConstant.InGameTime}后会重新补充一名雇佣兵。" + - (雇佣兵团.Count < 最小数量 && Skill.CurrentCD > 0 ? $"(下次补充:{Skill.CurrentCD} {GameplayEquilibriumConstant.InGameTime}后)" : ""); + (雇佣兵团.Count < 最小数量 && Skill.CurrentCD > 0 ? $"(下次补充:{Skill.CurrentCD:0.##} {GameplayEquilibriumConstant.InGameTime}后)" : ""); public List<雇佣兵> 雇佣兵团 { get; } = []; public const int 最小数量 = 1; @@ -58,6 +58,11 @@ namespace Oshima.FunGame.OshimaModules.Skills { WriteLine($"[ {killer} ] 杀死了 [ {death} ]!"); 雇佣兵团.Remove(gyb); + if (GamingQueue is Milimoe.FunGame.Core.Model.GamingQueue queue) + { + if (queue.Map != null) queue.RemoveCharacterFromMap(gyb); + else queue.RemoveCharacterFromQueue(gyb); + } if (雇佣兵团.Count < 最小数量 && Skill.CurrentCD == 0) { Skill.CurrentCD = 补充间隔; diff --git a/OshimaModules/Skills/被动/黑暗收割.cs b/OshimaModules/Skills/被动/黑暗收割.cs index 0c19059..ca8b272 100644 --- a/OshimaModules/Skills/被动/黑暗收割.cs +++ b/OshimaModules/Skills/被动/黑暗收割.cs @@ -10,6 +10,8 @@ namespace Oshima.FunGame.OshimaModules.Skills public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : ""; + public int 当前灵魂数量 { get; set; } = 0; + public 黑暗收割(Character? character = null) : base(SkillType.Passive, character) { Effects.Add(new 黑暗收割特效(this)); @@ -19,6 +21,14 @@ namespace Oshima.FunGame.OshimaModules.Skills { return Effects; } + + public override void OnCharacterRespawn(Skill newSkill) + { + if (newSkill is 黑暗收割 s) + { + s.当前灵魂数量 = 当前灵魂数量; + } + } } public class 黑暗收割特效(Skill skill) : Effect(skill) @@ -26,41 +36,41 @@ namespace Oshima.FunGame.OshimaModules.Skills public override long Id => Skill.Id; public override string Name => Skill.Name; public override string Description => $"{Skill.SkillOwner()}对一半以下生命值的目标造成伤害时,将收集其灵魂以永久提升自身伤害,每个灵魂提供 {额外伤害提升 * 100:0.##}% 伤害加成。最多收集 {最多灵魂数量} 个灵魂。" + - $"若{Skill.SkillOwner()}死亡,灵魂将损失一半。(当前灵魂数量:{当前灵魂数量} 个;伤害提升:{当前灵魂数量 * 额外伤害提升 * 100:0.##}%)"; + $"若{Skill.SkillOwner()}死亡,灵魂将损失一半。(当前灵魂数量:{CSkill?.当前灵魂数量} 个;伤害提升:{CSkill?.当前灵魂数量 * 额外伤害提升 * 100:0.##}%)"; + public 黑暗收割? CSkill => Skill is 黑暗收割 s ? s : null; private static double 额外伤害提升 => 0.02; - private int 当前灵魂数量 { get; set; } = 0; private int 最多灵魂数量 => Skill.Character != null ? 10 + Skill.Character.Level / 10 * 5 : 10; private bool 触发标记 { get; set; } = false; public override double AlterExpectedDamageBeforeCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, Dictionary totalDamageBonus) { - if (character == Skill.Character && (enemy.HP / enemy.MaxHP) < 0.5) + if (Skill is 黑暗收割 skill && character == Skill.Character && (enemy.HP / enemy.MaxHP) < 0.5) { 触发标记 = true; - return damage * 当前灵魂数量 * 额外伤害提升; + return damage * skill.当前灵魂数量 * 额外伤害提升; } return 0; } public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult) { - if (触发标记 && character == Skill.Character && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && 当前灵魂数量 < 最多灵魂数量) + if (触发标记 && character == Skill.Character && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && Skill is 黑暗收割 skill && skill.当前灵魂数量 < 最多灵魂数量) { 触发标记 = false; - 当前灵魂数量++; - WriteLine($"[ {character} ] 通过黑暗收割收集了一个灵魂!当前灵魂数:{当前灵魂数量}"); + skill.当前灵魂数量++; + WriteLine($"[ {character} ] 通过黑暗收割收集了一个灵魂!当前灵魂数:{skill.当前灵魂数量}"); } } public override void AfterDeathCalculation(Character death, bool hasMaster, Character? killer, Dictionary continuousKilling, Dictionary earnedMoney, Character[] assists) { - if (death == Skill.Character && 当前灵魂数量 > 0) + if (death == Skill.Character && Skill is 黑暗收割 skill && skill.当前灵魂数量 > 0) { - int lost = 当前灵魂数量 / 2; + int lost = skill.当前灵魂数量 / 2; if (lost > 0) { - 当前灵魂数量 -= lost; + skill.当前灵魂数量 -= lost; WriteLine($"[ {death} ] 因死亡损失了 [ {lost} ] 个灵魂!"); } } diff --git a/OshimaServers/Service/FunGameSimulation.cs b/OshimaServers/Service/FunGameSimulation.cs index a8251fd..8b51290 100644 --- a/OshimaServers/Service/FunGameSimulation.cs +++ b/OshimaServers/Service/FunGameSimulation.cs @@ -376,6 +376,11 @@ namespace Oshima.FunGame.OshimaServers.Service if (isWeb) actionQueue.DisplayQueue(); WriteLine(""); + if (actionQueue.Map != null) + { + WriteLine(DisplayMapInConsole(actionQueue.Map)); + WriteLine(""); + } } string roundMsg = ""; @@ -1294,5 +1299,51 @@ namespace Oshima.FunGame.OshimaServers.Service availableGrids[Random.Shared.Next(availableGrids.Count)] : null; } + + private static string DisplayMapInConsole(GameMap map) + { + StringBuilder sb = new(); + + // 打印列坐标 + sb.Append(" "); + for (int x = 0; x < map.Length; x++) + { + sb.Append($" {x} "); + } + sb.AppendLine(); + + for (int y = 0; y < map.Width; y++) + { + // 打印行坐标 + sb.Append($"{y} "); + + for (int x = 0; x < map.Length; x++) + { + Grid? grid = map[x, y, 0]; + + if (grid is null) + { + sb.Append(" "); + continue; + } + + // 检查格子上是否有角色 + if (grid.Characters.Count > 0) + { + // 取第一个角色的昵称首字母 + Character character = grid.Characters.First(); + string displayChar = character.NickName.Length > 0 ? character.NickName[0].ToString().ToUpper() : "?"; + sb.Append($"[{displayChar}] "); + } + else + { + sb.Append(" . "); + } + } + sb.AppendLine(); + } + + return sb.ToString(); + } } }