mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2026-01-19 14:08:22 +00:00
添加更多钩子,修复一些BUG
This commit is contained in:
parent
6325e9a956
commit
a93f9a274e
@ -726,7 +726,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
get
|
||||
{
|
||||
double value = SPD / GameplayEquilibriumConstant.SPDUpperLimit + ExActionCoefficient;
|
||||
return Calculation.PercentageCheck(value);
|
||||
return Math.Max(0, Math.Min(value, 0.9));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2210,7 +2210,8 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
Skill newskill = skill.Copy();
|
||||
newskill.Character = this;
|
||||
newskill.Level = skill.Level;
|
||||
newskill.CurrentCD = 0;
|
||||
newskill.CurrentCD = skill.CurrentCD;
|
||||
skill.OnCharacterRespawn(newskill);
|
||||
Skills.Add(newskill);
|
||||
}
|
||||
foreach (Item item in items)
|
||||
|
||||
@ -435,6 +435,20 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在技能释放前触发
|
||||
/// </summary>
|
||||
/// <param name="caster"></param>
|
||||
/// <param name="skill"></param>
|
||||
/// <param name="targets"></param>
|
||||
/// <param name="grids"></param>
|
||||
/// <param name="others"></param>
|
||||
/// <returns>返回 false 将角色从目标集合中移除</returns>
|
||||
public virtual bool BeforeSkillCasted(Character caster, Skill skill, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在时间流逝期间应用生命/魔法回复前修改 [ 允许取消回复 ]
|
||||
/// </summary>
|
||||
@ -581,9 +595,10 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
/// </summary>
|
||||
/// <param name="actor"></param>
|
||||
/// <param name="enemy"></param>
|
||||
/// <param name="isNormalAttack"></param>
|
||||
/// <param name="throwingBonus"></param>
|
||||
/// <returns>返回 false 表示不进行暴击检定</returns>
|
||||
public virtual bool BeforeCriticalCheck(Character actor, Character enemy, ref double throwingBonus)
|
||||
public virtual bool BeforeCriticalCheck(Character actor, Character enemy, bool isNormalAttack, ref double throwingBonus)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -880,6 +895,17 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在角色开始行动时触发
|
||||
/// </summary>
|
||||
/// <param name="actor"></param>
|
||||
/// <param name="dp"></param>
|
||||
/// <param name="type"></param>
|
||||
public virtual void OnCharacterActionStart(Character actor, DecisionPoints dp, CharacterActionType type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在角色行动后触发
|
||||
/// </summary>
|
||||
|
||||
@ -505,7 +505,7 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
|
||||
if (IsNonDirectional || CanSelectTargetRange < 0 || GamingQueue?.Map is not GameMap map)
|
||||
{
|
||||
return [];
|
||||
return [.. selected];
|
||||
}
|
||||
|
||||
foreach (Character selectedCharacter in selected)
|
||||
@ -652,6 +652,19 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
public void OnSkillCasted(IGamingQueue queue, Character caster, List<Character> targets, List<Grid> grids)
|
||||
{
|
||||
GamingQueue = queue;
|
||||
Character[] characters = [caster, .. targets];
|
||||
foreach (Character target in characters)
|
||||
{
|
||||
Effect[] effects = [.. target.Effects.Where(e => e.IsInEffect)];
|
||||
foreach (Effect e in effects)
|
||||
{
|
||||
e.GamingQueue = GamingQueue;
|
||||
if (!e.BeforeSkillCasted(caster, this, targets, grids, Values))
|
||||
{
|
||||
targets.Remove(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (Effect e in Effects)
|
||||
{
|
||||
e.GamingQueue = GamingQueue;
|
||||
@ -691,6 +704,16 @@ namespace Milimoe.FunGame.Core.Entity
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在复活时,因为复活是重新构建角色,如果需要继承死亡角色的技能数据,可以重写此方法并设置相关属性
|
||||
/// </summary>
|
||||
/// <param name="newSkill"></param>
|
||||
/// <returns></returns>
|
||||
public virtual void OnCharacterRespawn(Skill newSkill)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回技能的详细说明
|
||||
/// </summary>
|
||||
|
||||
@ -55,6 +55,11 @@ namespace Milimoe.FunGame.Core.Interface.Base
|
||||
/// </summary>
|
||||
public Dictionary<Character, CharacterStatistics> CharacterStatistics { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 助攻记录
|
||||
/// </summary>
|
||||
public Dictionary<Character, AssistDetail> AssistDetails { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色的决策点
|
||||
/// </summary>
|
||||
|
||||
11
Model/DeathRelation.cs
Normal file
11
Model/DeathRelation.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
|
||||
namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
public class DeathRelation(Character death, Character? killer, params Character[] assists)
|
||||
{
|
||||
public Character Death { get; set; } = death;
|
||||
public Character? Killer { get; set; } = killer;
|
||||
public Character[] Assists { get; set; } = assists;
|
||||
}
|
||||
}
|
||||
@ -67,6 +67,11 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// </summary>
|
||||
public Dictionary<Character, CharacterStatistics> CharacterStatistics => _stats;
|
||||
|
||||
/// <summary>
|
||||
/// 助攻记录
|
||||
/// </summary>
|
||||
public Dictionary<Character, AssistDetail> AssistDetails => _assistDetail;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏运行的时间
|
||||
/// </summary>
|
||||
@ -163,6 +168,11 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// </summary>
|
||||
public Dictionary<Character, DecisionPoints> CharacterDecisionPoints => _decisionPoints;
|
||||
|
||||
/// <summary>
|
||||
/// 游戏结束标识
|
||||
/// </summary>
|
||||
public bool GameOver => _isGameEnd;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 保护变量
|
||||
@ -260,7 +270,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <summary>
|
||||
/// 当前回合死亡角色和参与击杀的人
|
||||
/// </summary>
|
||||
protected readonly Dictionary<Character, Character[]> _roundDeaths = [];
|
||||
protected readonly List<DeathRelation> _roundDeaths = [];
|
||||
|
||||
/// <summary>
|
||||
/// 回合奖励
|
||||
@ -910,7 +920,8 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
|
||||
// 减少复活倒计时
|
||||
foreach (Character character in _respawnCountdown.Keys)
|
||||
Character[] willRespawns = [.. _respawnCountdown.Keys];
|
||||
foreach (Character character in willRespawns)
|
||||
{
|
||||
_respawnCountdown[character] = Calculation.Round2Digits(_respawnCountdown[character] - timeToReduce);
|
||||
if (_respawnCountdown[character] <= 0)
|
||||
@ -919,6 +930,8 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
}
|
||||
|
||||
ProcessCharacterDeath();
|
||||
|
||||
WriteLine("\r\n");
|
||||
|
||||
return timeToReduce;
|
||||
@ -1276,6 +1289,12 @@ namespace Milimoe.FunGame.Core.Model
|
||||
|
||||
int costDP = dp.GetActionPointCost(type);
|
||||
|
||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.OnCharacterActionStart(character, dp, type);
|
||||
}
|
||||
|
||||
if (type == CharacterActionType.Move)
|
||||
{
|
||||
if (_map != null)
|
||||
@ -1800,7 +1819,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
}
|
||||
|
||||
if (character.CharacterState != CharacterState.Casting)
|
||||
if (character.CharacterState != CharacterState.Casting && dp.ActionsHardnessTime.Count > 0)
|
||||
{
|
||||
baseTime = dp.ActionsTaken > 1 ? (dp.ActionsHardnessTime.Max() + dp.ActionsTaken) : dp.ActionsHardnessTime.Max();
|
||||
}
|
||||
@ -1819,7 +1838,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
|
||||
// 统一在回合结束时处理角色的死亡
|
||||
ProcessCharacterDeath(character);
|
||||
ProcessCharacterDeath();
|
||||
|
||||
// 移除回合奖励
|
||||
RemoveRoundRewards(character, rewards);
|
||||
@ -1899,29 +1918,20 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <summary>
|
||||
/// 处理角色死亡
|
||||
/// </summary>
|
||||
/// <param name="character"></param>
|
||||
protected void ProcessCharacterDeath(Character character)
|
||||
protected void ProcessCharacterDeath()
|
||||
{
|
||||
foreach (Character death in _roundDeaths.Keys)
|
||||
foreach (DeathRelation dr in _roundDeaths)
|
||||
{
|
||||
Character[] assists = _roundDeaths[death];
|
||||
Character death = dr.Death;
|
||||
Character? killer = dr.Killer;
|
||||
Character[] assists = dr.Assists;
|
||||
|
||||
if (!OnCharacterDeathEvent(character, death, assists))
|
||||
if (!_isGameEnd)
|
||||
{
|
||||
continue;
|
||||
AfterDeathCalculation(death, killer, assists);
|
||||
}
|
||||
|
||||
// 给所有角色的特效广播角色死亡结算
|
||||
List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.IsInEffect))];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.AfterDeathCalculation(death, character, _continuousKilling, _earnedMoney, assists);
|
||||
}
|
||||
// 将死者移出队列
|
||||
_queue.Remove(death);
|
||||
|
||||
AfterDeathCalculation(death, character, assists);
|
||||
}
|
||||
_roundDeaths.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1967,17 +1977,24 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="death"></param>
|
||||
/// <param name="killer"></param>
|
||||
/// <param name="assists"></param>
|
||||
protected virtual void AfterDeathCalculation(Character death, Character killer, Character[] assists)
|
||||
protected virtual void AfterDeathCalculation(Character death, Character? killer, Character[] assists)
|
||||
{
|
||||
if (!_queue.Any(c => c != killer && c.Master != killer && killer.Master != c))
|
||||
if (!_queue.Any(c => c != killer && c.Master != killer && killer?.Master != c))
|
||||
{
|
||||
// 没有其他的角色了,游戏结束
|
||||
if (killer != null)
|
||||
{
|
||||
WriteLine("[ " + killer + " ] 是胜利者。");
|
||||
_queue.Remove(killer);
|
||||
_eliminated.Add(killer);
|
||||
_isGameEnd = true;
|
||||
OnGameEndEvent(killer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("游戏结束。");
|
||||
}
|
||||
_isGameEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2389,7 +2406,6 @@ namespace Milimoe.FunGame.Core.Model
|
||||
if (enemy.HP <= 0 && !_eliminated.Contains(enemy) && !_respawnCountdown.ContainsKey(enemy))
|
||||
{
|
||||
LastRound.HasKill = true;
|
||||
_roundDeaths.Add(enemy, []);
|
||||
DeathCalculation(actor, enemy);
|
||||
}
|
||||
}
|
||||
@ -2401,6 +2417,9 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="death"></param>
|
||||
public void DeathCalculation(Character killer, Character death)
|
||||
{
|
||||
DeathRelation dr = new(death, killer);
|
||||
_roundDeaths.Add(dr);
|
||||
|
||||
if (killer == death)
|
||||
{
|
||||
if (!OnDeathCalculationEvent(killer, death))
|
||||
@ -2453,6 +2472,9 @@ namespace Milimoe.FunGame.Core.Model
|
||||
Character[] assists = [.. _assistDetail.Keys.Where(c => c != death &&
|
||||
((TotalTime - _assistDetail[c].GetLastTime(death) <= 30) || (TotalTime - _assistDetail[c].GetNotDamageAssistLastTime(killer) <= 20)))];
|
||||
|
||||
// 获取队友列表
|
||||
Character[] teammates = [.. GetTeammates(killer)];
|
||||
|
||||
// 获取贡献百分比 以伤害为主,非伤害助攻贡献不足 10% 的按 10% 计算
|
||||
double minPercentage = 0.1;
|
||||
Dictionary<Character, double> assistPercentage = _assistDetail.Keys.Where(assists.Contains).ToDictionary(c => c,
|
||||
@ -2509,7 +2531,10 @@ namespace Milimoe.FunGame.Core.Model
|
||||
cmoney += calDiff(death, assist);
|
||||
if (!_earnedMoney.TryAdd(assist, cmoney)) _earnedMoney[assist] += cmoney;
|
||||
assist.User.Inventory.Credits += cmoney;
|
||||
if (teammates.Length == 0 || (teammates.Length > 0 && teammates.Contains(assist)))
|
||||
{
|
||||
_stats[assist].Assists += 1;
|
||||
}
|
||||
if (!LastRound.Assists.Contains(assist)) LastRound.Assists.Add(assist);
|
||||
}
|
||||
else
|
||||
@ -2544,7 +2569,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
WriteLine(msg);
|
||||
}
|
||||
_roundDeaths[death] = assists;
|
||||
dr.Assists = assists;
|
||||
|
||||
if (FirstKiller is null)
|
||||
{
|
||||
@ -2586,6 +2611,17 @@ namespace Milimoe.FunGame.Core.Model
|
||||
}
|
||||
|
||||
DealWithCharacterDied(killer, death);
|
||||
|
||||
// 给所有角色的特效广播角色死亡结算
|
||||
List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Union(killer.Effects).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
effect.AfterDeathCalculation(death, killer, _continuousKilling, _earnedMoney, assists);
|
||||
}
|
||||
// 将死者移出队列
|
||||
_queue.Remove(death);
|
||||
|
||||
OnCharacterDeathEvent(death, killer, assists);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2630,6 +2666,12 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="triggerEffects"></param>
|
||||
public void HealToTarget(Character actor, Character target, double heal, bool canRespawn = false, bool triggerEffects = true)
|
||||
{
|
||||
// 死人怎么能对自己治疗呢?
|
||||
if (actor.HP <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.HP == target.MaxHP)
|
||||
{
|
||||
return;
|
||||
@ -3287,7 +3329,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus))
|
||||
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
||||
{
|
||||
checkCritical = false;
|
||||
}
|
||||
@ -3414,7 +3456,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
||||
foreach (Effect effect in effects)
|
||||
{
|
||||
if (!effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus))
|
||||
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
||||
{
|
||||
checkCritical = false;
|
||||
}
|
||||
@ -4189,7 +4231,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
stats.TotalTrueDamage += damage;
|
||||
}
|
||||
if (damageType == DamageType.Magical)
|
||||
else if (damageType == DamageType.Magical)
|
||||
{
|
||||
stats.TotalMagicDamage += damage;
|
||||
}
|
||||
@ -4205,7 +4247,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
{
|
||||
statsTaken.TotalTakenTrueDamage = Calculation.Round2Digits(statsTaken.TotalTakenTrueDamage + takenDamage);
|
||||
}
|
||||
if (damageType == DamageType.Magical)
|
||||
else if (damageType == DamageType.Magical)
|
||||
{
|
||||
statsTaken.TotalTakenMagicDamage = Calculation.Round2Digits(statsTaken.TotalTakenMagicDamage + takenDamage);
|
||||
}
|
||||
@ -4513,7 +4555,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
return DeathCalculationByTeammateEvent?.Invoke(this, killer, death) ?? true;
|
||||
}
|
||||
|
||||
public delegate bool CharacterDeathEventHandler(GamingQueue queue, Character current, Character death, Character[] assists);
|
||||
public delegate bool CharacterDeathEventHandler(GamingQueue queue, Character death, Character? killer, Character[] assists);
|
||||
/// <summary>
|
||||
/// 角色死亡事件,此事件位于 <see cref="DeathCalculation"/> 之后
|
||||
/// </summary>
|
||||
@ -4521,13 +4563,13 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <summary>
|
||||
/// 角色死亡事件,此事件位于 <see cref="DeathCalculation"/> 之后
|
||||
/// </summary>
|
||||
/// <param name="current"></param>
|
||||
/// <param name="death"></param>
|
||||
/// <param name="killer"></param>
|
||||
/// <param name="assists"></param>
|
||||
/// <returns></returns>
|
||||
protected bool OnCharacterDeathEvent(Character current, Character death, Character[] assists)
|
||||
protected bool OnCharacterDeathEvent(Character death, Character? killer, Character[] assists)
|
||||
{
|
||||
return CharacterDeathEvent?.Invoke(this, current, death, assists) ?? true;
|
||||
return CharacterDeathEvent?.Invoke(this, death, killer, assists) ?? true;
|
||||
}
|
||||
|
||||
public delegate void HealToTargetEventHandler(GamingQueue queue, Character actor, Character target, double heal, bool isRespawn);
|
||||
|
||||
@ -15,7 +15,7 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="killer"></param>
|
||||
/// <param name="assists"></param>
|
||||
/// <returns></returns>
|
||||
protected override void AfterDeathCalculation(Character death, Character killer, Character[] assists)
|
||||
protected override void AfterDeathCalculation(Character death, Character? killer, Character[] assists)
|
||||
{
|
||||
if (MaxRespawnTimes != 0 && MaxScoreToWin > 0)
|
||||
{
|
||||
@ -23,13 +23,13 @@ namespace Milimoe.FunGame.Core.Model
|
||||
.Select(kv => $"[ {kv.Key} ] {kv.Value.Kills} 分"))}\r\n剩余存活人数:{_queue.Count}");
|
||||
}
|
||||
|
||||
if (!_queue.Any(c => c != killer && c.Master != killer && killer.Master != c))
|
||||
if (!_queue.Any(c => c != killer && c.Master != killer && killer?.Master != c))
|
||||
{
|
||||
// 没有其他的角色了,游戏结束
|
||||
EndGameInfo(killer);
|
||||
}
|
||||
|
||||
if (MaxScoreToWin > 0 && _stats[killer].Kills >= MaxScoreToWin)
|
||||
if (MaxScoreToWin > 0 && killer != null && _stats[killer].Kills >= MaxScoreToWin)
|
||||
{
|
||||
EndGameInfo(killer);
|
||||
return;
|
||||
@ -58,8 +58,14 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <summary>
|
||||
/// 游戏结束信息
|
||||
/// </summary>
|
||||
public void EndGameInfo(Character winner)
|
||||
public void EndGameInfo(Character? winner)
|
||||
{
|
||||
winner ??= _queue.FirstOrDefault();
|
||||
if (winner is null)
|
||||
{
|
||||
WriteLine("游戏结束。");
|
||||
return;
|
||||
}
|
||||
WriteLine("[ " + winner + " ] 是胜利者。");
|
||||
foreach (Character character in _stats.OrderBy(kv => kv.Value.Kills)
|
||||
.ThenByDescending(kv => kv.Value.Deaths)
|
||||
|
||||
@ -159,8 +159,15 @@ namespace Milimoe.FunGame.Core.Model
|
||||
/// <param name="killer"></param>
|
||||
/// <param name="assists"></param>
|
||||
/// <returns></returns>
|
||||
protected override void AfterDeathCalculation(Character death, Character killer, Character[] assists)
|
||||
protected override void AfterDeathCalculation(Character death, Character? killer, Character[] assists)
|
||||
{
|
||||
killer ??= _queue.FirstOrDefault();
|
||||
if (killer is null)
|
||||
{
|
||||
WriteLine("游戏结束。");
|
||||
return;
|
||||
}
|
||||
|
||||
Team? killTeam = GetTeam(killer);
|
||||
Team? deathTeam = GetTeam(death);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user