添加更多事件和钩子;添加 OnSkillCasted 前自动豁免;完善魔法效能

This commit is contained in:
milimoe 2026-01-20 01:56:24 +08:00
parent 4bd706c43c
commit 8d3d19737c
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
5 changed files with 90 additions and 19 deletions

View File

@ -179,6 +179,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public virtual bool ExemptDuration { get; set; } = false;
/// <summary>
/// 魔法效能% [ 来自技能 ]
/// </summary>
public double MagicEfficacy => Skill.MagicEfficacy;
/// <summary>
/// 效果描述
/// </summary>
@ -256,6 +261,14 @@ namespace Milimoe.FunGame.Core.Entity
}
/// <summary>
/// 游戏开始时触发(第一回合开始前)
/// </summary>
public virtual void OnGameStart()
{
}
/// <summary>
/// 在伤害计算前修改伤害类型
/// </summary>
@ -1004,7 +1017,7 @@ namespace Milimoe.FunGame.Core.Entity
/// <param name="triggerEffects"></param>
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true)
{
GamingQueue?.HealToTarget(actor, target, heal, canRespawn, triggerEffects);
GamingQueue?.HealToTarget(actor, target, heal, canRespawn, triggerEffects, Skill);
}
/// <summary>

View File

@ -266,7 +266,7 @@ namespace Milimoe.FunGame.Core.Entity
public virtual double CD { get; set; } = 0;
/// <summary>
/// 剩余冷却时间 [ 建议配合 <see cref="Enable"/> 属性使用 ]
/// 剩余冷却时间 [ 和 <see cref="Enable"/> 属性配合使用 ]
/// </summary>
public double CurrentCD { get; set; } = 0;
@ -345,6 +345,11 @@ namespace Milimoe.FunGame.Core.Entity
/// </summary>
public Item? Item { get; set; } = null;
/// <summary>
/// 设置该属性可以由框架自动进行豁免检定
/// </summary>
public virtual Effect? EffectForExemptionCheck { get; set; } = null;
/// <summary>
/// 继承此类实现时,调用基类的构造函数
/// </summary>
@ -696,6 +701,17 @@ namespace Milimoe.FunGame.Core.Entity
public void OnSkillCasted(IGamingQueue queue, Character caster, List<Character> targets, List<Grid> grids)
{
GamingQueue = queue;
if (EffectForExemptionCheck != null)
{
Character[] exemptionTargets = [.. targets];
foreach (Character target in exemptionTargets)
{
if (!GamingQueue.CheckExemption(target, caster, EffectForExemptionCheck, true))
{
targets.Remove(target);
}
}
}
Character[] characters = [caster, .. targets];
foreach (Character target in characters)
{

View File

@ -114,7 +114,8 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="heal"></param>
/// <param name="canRespawn"></param>
/// <param name="triggerEffects"></param>
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true);
/// <param name="skill"></param>
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true, Skill? skill = null);
/// <summary>
/// 计算物理伤害

View File

@ -213,12 +213,12 @@ namespace Milimoe.FunGame.Core.Model
/// <summary>
/// 每 1 点力量增加生命值
/// </summary>
public double STRtoHPFactor { get; set; } = 9;
public double STRtoHPFactor { get; set; } = 13;
/// <summary>
/// 每 1 点力量增加生命回复力
/// </summary>
public double STRtoHRFactor { get; set; } = 0.1;
public double STRtoHRFactor { get; set; } = 0.15;
/// <summary>
/// 每 1 点力量增加物理护甲
@ -248,7 +248,7 @@ namespace Milimoe.FunGame.Core.Model
/// <summary>
/// 每 1 点智力增加魔法回复力
/// </summary>
public double INTtoMRFactor { get; set; } = 0.04;
public double INTtoMRFactor { get; set; } = 0.1;
/// <summary>
/// 每 1 点智力减少魔法消耗

View File

@ -703,14 +703,25 @@ namespace Milimoe.FunGame.Core.Model
if (character != null)
{
_queue.Remove(character);
_cutCount.Remove(character);
// 进入下一回合
TotalRound++;
LastRound = new(TotalRound);
Rounds.Add(LastRound);
if (TotalRound == 1)
{
// 触发游戏开始事件
OnGameStartEvent();
Effect[] effects = [.. _queue.SelectMany(c => c.Effects).Where(e => e.IsInEffect)];
foreach (Effect effect in effects)
{
effect.OnGameStart();
}
}
_queue.Remove(character);
_cutCount.Remove(character);
return character;
}
else
@ -817,13 +828,18 @@ namespace Milimoe.FunGame.Core.Model
}
// 减少所有技能的冷却时间
foreach (Skill skill in character.Skills)
List<Skill> skills = [.. character.Skills.Union(character.Items.Where(i => i.Skills.Active != null).Select(i => i.Skills.Active!))];
AddCharacterEquipSlotSkills(character, skills);
foreach (Skill skill in skills)
{
skill.CurrentCD -= timeToReduce;
if (skill.CurrentCD <= 0)
if (skill.CurrentCD > 0)
{
skill.CurrentCD = 0;
skill.Enable = true;
skill.CurrentCD -= timeToReduce;
if (skill.CurrentCD <= 0)
{
skill.CurrentCD = 0;
skill.Enable = true;
}
}
}
@ -2691,7 +2707,8 @@ namespace Milimoe.FunGame.Core.Model
/// <param name="heal"></param>
/// <param name="canRespawn"></param>
/// <param name="triggerEffects"></param>
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true)
/// <param name="skill"></param>
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true, Skill? skill = null)
{
// 死人怎么能对自己治疗呢?
if (actor.HP <= 0)
@ -2720,7 +2737,8 @@ namespace Milimoe.FunGame.Core.Model
}
bool isDead = target.HP <= 0;
string healString = $"【{heal:0.##}(基础)";
List<string> healStrings = [];
healStrings.Add($"{heal:0.##}(基础)");
if (triggerEffects)
{
@ -2737,13 +2755,22 @@ namespace Milimoe.FunGame.Core.Model
if (healBonus != 0)
{
totalHealBonus[effect]= healBonus;
healString += $"{(healBonus > 0 ? " + " : " - ")}{Math.Abs(healBonus):0.##}{effect.Name}";
healStrings.Add($"{(healBonus > 0 ? " + " : " - ")}{Math.Abs(healBonus):0.##}{effect.Name}");
}
}
heal += totalHealBonus.Sum(kv => kv.Value);
}
healString += $" = {heal:0.##} 点生命值】";
if (!IsDebug) healString = "";
if (skill != null && skill.MagicBottleneck > 0)
{
double efficacyHeal = heal * (skill.MagicEfficacy - 1);
heal *= skill.MagicEfficacy;
healStrings.Add($"{(efficacyHeal >= 0 ? " + " : " - ")}{Math.Abs(efficacyHeal):0.##}(魔法效能:{skill.MagicEfficacy * 100:0.##}%");
}
healStrings.Add($" = {heal:0.##} 点生命值");
if (!IsDebug) healStrings.Clear();
string healString = $"【{string.Join("", healStrings)}】";
if (target.HP > 0 || (isDead && canRespawn))
{
@ -4887,6 +4914,20 @@ namespace Milimoe.FunGame.Core.Model
CharacterMoveEvent?.Invoke(this, actor, dp, grid);
}
public delegate void GameStartEventHandler(GamingQueue queue);
/// <summary>
/// 游戏开始事件
/// </summary>
public event GameStartEventHandler? GameStartEvent;
/// <summary>
/// 游戏开始事件
/// </summary>
/// <returns></returns>
protected void OnGameStartEvent()
{
GameStartEvent?.Invoke(this);
}
public delegate bool GameEndEventHandler(GamingQueue queue, Character winner);
/// <summary>
/// 游戏结束事件