mirror of
https://github.com/project-redbud/FunGame-Core.git
synced 2026-03-05 22:20:26 +00:00
添加特效触发优先级;将行动偏好的概率值引入战棋模式;添加询问可取消机制
This commit is contained in:
parent
97a5c0ac41
commit
f75699d5ff
@ -24,11 +24,29 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
/// <param name="allTeammatesInGame">场上所有队友</param>
|
/// <param name="allTeammatesInGame">场上所有队友</param>
|
||||||
/// <param name="selectableEnemys">场上能够选取的敌人</param>
|
/// <param name="selectableEnemys">场上能够选取的敌人</param>
|
||||||
/// <param name="selectableTeammates">场上能够选取的队友</param>
|
/// <param name="selectableTeammates">场上能够选取的队友</param>
|
||||||
|
/// <param name="pUseItem">使用物品的概率</param>
|
||||||
|
/// <param name="pCastSkill">释放技能的概率</param>
|
||||||
|
/// <param name="pNormalAttack">普通攻击的概率</param>
|
||||||
/// <returns>包含最佳行动的AIDecision对象</returns>
|
/// <returns>包含最佳行动的AIDecision对象</returns>
|
||||||
public AIDecision DecideAIAction(Character character, DecisionPoints dp, Grid startGrid, List<Grid> allPossibleMoveGrids,
|
public AIDecision DecideAIAction(Character character, DecisionPoints dp, Grid startGrid, List<Grid> allPossibleMoveGrids,
|
||||||
List<Skill> availableSkills, List<Item> availableItems, List<Character> allEnemysInGame, List<Character> allTeammatesInGame,
|
List<Skill> availableSkills, List<Item> availableItems, List<Character> allEnemysInGame, List<Character> allTeammatesInGame,
|
||||||
List<Character> selectableEnemys, List<Character> selectableTeammates)
|
List<Character> selectableEnemys, List<Character> selectableTeammates, double pUseItem, double pCastSkill, double pNormalAttack)
|
||||||
{
|
{
|
||||||
|
// 动态调整概率
|
||||||
|
double dynamicPUseItem = pUseItem;
|
||||||
|
double dynamicPCastSkill = pCastSkill;
|
||||||
|
double dynamicPNormalAttack = pNormalAttack;
|
||||||
|
AdjustProbabilitiesBasedOnContext(ref dynamicPUseItem, ref dynamicPCastSkill, ref dynamicPNormalAttack, character, allEnemysInGame, allTeammatesInGame);
|
||||||
|
|
||||||
|
// 归一化概率
|
||||||
|
double[] normalizedProbs = NormalizeProbabilities(dynamicPUseItem, dynamicPCastSkill, dynamicPNormalAttack);
|
||||||
|
double normalizedPUseItem = normalizedProbs[0];
|
||||||
|
double normalizedPCastSkill = normalizedProbs[1];
|
||||||
|
double normalizedPNormalAttack = normalizedProbs[2];
|
||||||
|
|
||||||
|
// 获取偏好行动类型
|
||||||
|
CharacterActionType? preferredAction = GetPreferredActionType(pUseItem, pCastSkill, pNormalAttack);
|
||||||
|
|
||||||
// 初始化一个默认的“结束回合”决策作为基准
|
// 初始化一个默认的“结束回合”决策作为基准
|
||||||
AIDecision bestDecision = new()
|
AIDecision bestDecision = new()
|
||||||
{
|
{
|
||||||
@ -38,6 +56,9 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
Score = -1000.0
|
Score = -1000.0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 候选决策
|
||||||
|
List<AIDecision> candidateDecisions = [];
|
||||||
|
|
||||||
// 遍历所有可能的移动目标格子 (包括起始格子本身)
|
// 遍历所有可能的移动目标格子 (包括起始格子本身)
|
||||||
foreach (Grid potentialMoveGrid in allPossibleMoveGrids)
|
foreach (Grid potentialMoveGrid in allPossibleMoveGrids)
|
||||||
{
|
{
|
||||||
@ -45,75 +66,79 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
int moveDistance = GameMap.CalculateManhattanDistance(startGrid, potentialMoveGrid);
|
int moveDistance = GameMap.CalculateManhattanDistance(startGrid, potentialMoveGrid);
|
||||||
double movePenalty = moveDistance * 0.5; // 每移动一步扣0.5分
|
double movePenalty = moveDistance * 0.5; // 每移动一步扣0.5分
|
||||||
|
|
||||||
if (CanCharacterNormalAttack(character, dp))
|
if (pNormalAttack > 0)
|
||||||
{
|
{
|
||||||
// 计算普通攻击的可达格子
|
if (CanCharacterNormalAttack(character, dp))
|
||||||
List<Grid> normalAttackReachableGrids = _map.GetGridsByRange(potentialMoveGrid, character.ATR, true);
|
|
||||||
|
|
||||||
List<Character> normalAttackReachableEnemys = [.. allEnemysInGame.Where(c => normalAttackReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
|
||||||
List<Character> normalAttackReachableTeammates = [.. allTeammatesInGame.Where(c => normalAttackReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
|
||||||
|
|
||||||
if (normalAttackReachableEnemys.Count > 0)
|
|
||||||
{
|
{
|
||||||
// 将筛选后的目标列表传递给 SelectTargets
|
// 计算普通攻击的可达格子
|
||||||
List<Character> targets = SelectTargets(character, character.NormalAttack, normalAttackReachableEnemys, normalAttackReachableTeammates);
|
List<Grid> normalAttackReachableGrids = _map.GetGridsByRange(potentialMoveGrid, character.ATR, true);
|
||||||
if (targets.Count > 0)
|
|
||||||
|
List<Character> normalAttackReachableEnemys = [.. allEnemysInGame.Where(c => normalAttackReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
||||||
|
List<Character> normalAttackReachableTeammates = [.. allTeammatesInGame.Where(c => normalAttackReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
||||||
|
|
||||||
|
if (normalAttackReachableEnemys.Count > 0)
|
||||||
{
|
{
|
||||||
double currentScore = EvaluateNormalAttack(character, targets) - movePenalty;
|
// 将筛选后的目标列表传递给 SelectTargets
|
||||||
if (currentScore > bestDecision.Score)
|
List<Character> targets = SelectTargets(character, character.NormalAttack, normalAttackReachableEnemys, normalAttackReachableTeammates);
|
||||||
|
if (targets.Count > 0)
|
||||||
{
|
{
|
||||||
bestDecision = new AIDecision
|
double currentScore = EvaluateNormalAttack(character, targets) - movePenalty;
|
||||||
|
double probabilityWeight = 1.0 + (normalizedPNormalAttack * 0.3);
|
||||||
|
candidateDecisions.Add(new AIDecision
|
||||||
{
|
{
|
||||||
ActionType = CharacterActionType.NormalAttack,
|
ActionType = CharacterActionType.NormalAttack,
|
||||||
TargetMoveGrid = potentialMoveGrid,
|
TargetMoveGrid = potentialMoveGrid,
|
||||||
SkillToUse = character.NormalAttack,
|
SkillToUse = character.NormalAttack,
|
||||||
Targets = targets,
|
Targets = targets,
|
||||||
Score = currentScore
|
Score = currentScore,
|
||||||
};
|
ProbabilityWeight = probabilityWeight
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Skill skill in availableSkills)
|
if (pCastSkill > 0)
|
||||||
{
|
{
|
||||||
if (CanCharacterUseSkill(character, skill, dp) && _queue.CheckCanCast(character, skill, out double cost))
|
foreach (Skill skill in availableSkills)
|
||||||
{
|
{
|
||||||
// 计算当前技能的可达格子
|
if (CanCharacterUseSkill(character, skill, dp) && _queue.CheckCanCast(character, skill, out double cost))
|
||||||
List<Grid> skillReachableGrids = _map.GetGridsByRange(potentialMoveGrid, skill.CastRange, true);
|
|
||||||
|
|
||||||
if (skill.IsNonDirectional)
|
|
||||||
{
|
{
|
||||||
AIDecision? nonDirDecision = EvaluateNonDirectionalSkill(character, skill, potentialMoveGrid, skillReachableGrids, allEnemysInGame, allTeammatesInGame, cost);
|
// 计算当前技能的可达格子
|
||||||
|
List<Grid> skillReachableGrids = _map.GetGridsByRange(potentialMoveGrid, skill.CastRange, true);
|
||||||
|
|
||||||
if (nonDirDecision != null && nonDirDecision.Score > bestDecision.Score)
|
if (skill.IsNonDirectional)
|
||||||
{
|
{
|
||||||
bestDecision = nonDirDecision;
|
AIDecision? nonDirDecision = EvaluateNonDirectionalSkill(character, skill, potentialMoveGrid, skillReachableGrids, allEnemysInGame, allTeammatesInGame, cost);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<Character> skillReachableEnemys = [.. allEnemysInGame.Where(c => skillReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
|
||||||
List<Character> skillReachableTeammates = [.. allTeammatesInGame.Where(c => skillReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
|
||||||
|
|
||||||
// 检查是否有可用的目标(敌人或队友,取决于技能类型)
|
if (nonDirDecision != null && nonDirDecision.Score > bestDecision.Score)
|
||||||
if (skillReachableEnemys.Count > 0 || skillReachableTeammates.Count > 0)
|
|
||||||
{
|
|
||||||
// 将筛选后的目标列表传递给 SelectTargets
|
|
||||||
List<Character> targets = SelectTargets(character, skill, skillReachableEnemys, skillReachableTeammates);
|
|
||||||
if (targets.Count > 0)
|
|
||||||
{
|
{
|
||||||
double currentScore = EvaluateSkill(character, skill, targets, cost) - movePenalty;
|
bestDecision = nonDirDecision;
|
||||||
if (currentScore > bestDecision.Score)
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<Character> skillReachableEnemys = [.. allEnemysInGame.Where(c => skillReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
||||||
|
List<Character> skillReachableTeammates = [.. allTeammatesInGame.Where(c => skillReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
||||||
|
|
||||||
|
// 检查是否有可用的目标(敌人或队友,取决于技能类型)
|
||||||
|
if (skillReachableEnemys.Count > 0 || skillReachableTeammates.Count > 0)
|
||||||
|
{
|
||||||
|
// 将筛选后的目标列表传递给 SelectTargets
|
||||||
|
List<Character> targets = SelectTargets(character, skill, skillReachableEnemys, skillReachableTeammates);
|
||||||
|
if (targets.Count > 0)
|
||||||
{
|
{
|
||||||
bestDecision = new AIDecision
|
double currentScore = EvaluateSkill(character, skill, targets, cost) - movePenalty;
|
||||||
|
double probabilityWeight = 1.0 + (normalizedPCastSkill * 0.3);
|
||||||
|
candidateDecisions.Add(new AIDecision
|
||||||
{
|
{
|
||||||
ActionType = CharacterActionType.PreCastSkill,
|
ActionType = CharacterActionType.PreCastSkill,
|
||||||
TargetMoveGrid = potentialMoveGrid,
|
TargetMoveGrid = potentialMoveGrid,
|
||||||
SkillToUse = skill,
|
SkillToUse = skill,
|
||||||
Targets = targets,
|
Targets = targets,
|
||||||
Score = currentScore
|
Score = currentScore,
|
||||||
};
|
ProbabilityWeight = probabilityWeight
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,48 +146,50 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Item item in availableItems)
|
if (pUseItem > 0)
|
||||||
{
|
{
|
||||||
if (item.Skills.Active != null && CanCharacterUseItem(character, item, dp) && _queue.CheckCanCast(character, item.Skills.Active, out double cost))
|
foreach (Item item in availableItems)
|
||||||
{
|
{
|
||||||
Skill itemSkill = item.Skills.Active;
|
if (item.Skills.Active != null && CanCharacterUseItem(character, item, dp) && _queue.CheckCanCast(character, item.Skills.Active, out double cost))
|
||||||
|
|
||||||
// 计算当前物品技能的可达格子
|
|
||||||
List<Grid> itemSkillReachableGrids = _map.GetGridsByRange(potentialMoveGrid, itemSkill.CastRange, true);
|
|
||||||
|
|
||||||
if (itemSkill.IsNonDirectional)
|
|
||||||
{
|
{
|
||||||
AIDecision? nonDirDecision = EvaluateNonDirectionalSkill(character, itemSkill, potentialMoveGrid, itemSkillReachableGrids, allEnemysInGame, allTeammatesInGame, cost);
|
Skill itemSkill = item.Skills.Active;
|
||||||
|
|
||||||
if (nonDirDecision != null && nonDirDecision.Score > bestDecision.Score)
|
// 计算当前物品技能的可达格子
|
||||||
{
|
List<Grid> itemSkillReachableGrids = _map.GetGridsByRange(potentialMoveGrid, itemSkill.CastRange, true);
|
||||||
bestDecision = nonDirDecision;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<Character> itemSkillReachableEnemys = [.. allEnemysInGame.Where(c => itemSkillReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
|
||||||
List<Character> itemSkillReachableTeammates = [.. allTeammatesInGame.Where(c => itemSkillReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
|
||||||
|
|
||||||
// 检查是否有可用的目标
|
if (itemSkill.IsNonDirectional)
|
||||||
if (itemSkillReachableEnemys.Count > 0 || itemSkillReachableTeammates.Count > 0)
|
|
||||||
{
|
{
|
||||||
// 将筛选后的目标列表传递给 SelectTargets
|
AIDecision? nonDirDecision = EvaluateNonDirectionalSkill(character, itemSkill, potentialMoveGrid, itemSkillReachableGrids, allEnemysInGame, allTeammatesInGame, cost);
|
||||||
List<Character> targetsForItem = SelectTargets(character, itemSkill, itemSkillReachableEnemys, itemSkillReachableTeammates);
|
|
||||||
if (targetsForItem.Count > 0)
|
if (nonDirDecision != null && nonDirDecision.Score > bestDecision.Score)
|
||||||
{
|
{
|
||||||
double currentScore = EvaluateItem(character, item, targetsForItem, cost) - movePenalty;
|
bestDecision = nonDirDecision;
|
||||||
if (currentScore > bestDecision.Score)
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<Character> itemSkillReachableEnemys = [.. allEnemysInGame.Where(c => itemSkillReachableGrids.SelectMany(g => g.Characters).Contains(c) && !c.IsUnselectable && selectableEnemys.Contains(c)).Distinct()];
|
||||||
|
List<Character> itemSkillReachableTeammates = [.. allTeammatesInGame.Where(c => itemSkillReachableGrids.SelectMany(g => g.Characters).Contains(c) && selectableTeammates.Contains(c)).Distinct()];
|
||||||
|
|
||||||
|
// 检查是否有可用的目标
|
||||||
|
if (itemSkillReachableEnemys.Count > 0 || itemSkillReachableTeammates.Count > 0)
|
||||||
|
{
|
||||||
|
// 将筛选后的目标列表传递给 SelectTargets
|
||||||
|
List<Character> targetsForItem = SelectTargets(character, itemSkill, itemSkillReachableEnemys, itemSkillReachableTeammates);
|
||||||
|
if (targetsForItem.Count > 0)
|
||||||
{
|
{
|
||||||
bestDecision = new AIDecision
|
double currentScore = EvaluateItem(character, item, targetsForItem, cost) - movePenalty;
|
||||||
|
double probabilityWeight = 1.0 + (normalizedPUseItem * 0.3);
|
||||||
|
candidateDecisions.Add(new AIDecision
|
||||||
{
|
{
|
||||||
ActionType = CharacterActionType.UseItem,
|
ActionType = CharacterActionType.UseItem,
|
||||||
TargetMoveGrid = potentialMoveGrid,
|
TargetMoveGrid = potentialMoveGrid,
|
||||||
ItemToUse = item,
|
ItemToUse = item,
|
||||||
SkillToUse = itemSkill,
|
SkillToUse = itemSkill,
|
||||||
Targets = targetsForItem,
|
Targets = targetsForItem,
|
||||||
Score = currentScore
|
Score = currentScore,
|
||||||
};
|
ProbabilityWeight = probabilityWeight
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,19 +236,30 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果纯粹移动比当前最佳(什么都不做)更好
|
candidateDecisions.Add(new AIDecision
|
||||||
if (pureMoveScore > bestDecision.Score)
|
|
||||||
{
|
{
|
||||||
bestDecision = new AIDecision
|
ActionType = CharacterActionType.Move,
|
||||||
|
TargetMoveGrid = potentialMoveGrid,
|
||||||
|
Targets = [],
|
||||||
|
Score = pureMoveScore,
|
||||||
|
IsPureMove = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 偏好类型额外加分
|
||||||
|
if (preferredAction.HasValue)
|
||||||
|
{
|
||||||
|
foreach (var decision in candidateDecisions)
|
||||||
|
{
|
||||||
|
if (decision.ActionType == preferredAction.Value)
|
||||||
{
|
{
|
||||||
ActionType = CharacterActionType.Move,
|
decision.Score *= 1.2;
|
||||||
TargetMoveGrid = potentialMoveGrid,
|
}
|
||||||
Targets = [],
|
|
||||||
Score = pureMoveScore,
|
|
||||||
IsPureMove = true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 最终决策
|
||||||
|
bestDecision = candidateDecisions.OrderByDescending(d => d.Score * d.ProbabilityWeight).FirstOrDefault() ?? bestDecision;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestDecision;
|
return bestDecision;
|
||||||
@ -229,6 +267,79 @@ namespace Milimoe.FunGame.Core.Controller
|
|||||||
|
|
||||||
// --- AI 决策辅助方法 ---
|
// --- AI 决策辅助方法 ---
|
||||||
|
|
||||||
|
// 获取偏好行动类型
|
||||||
|
private static CharacterActionType? GetPreferredActionType(double pItem, double pSkill, double pAttack)
|
||||||
|
{
|
||||||
|
// 找出最高概率的行动类型
|
||||||
|
Dictionary<CharacterActionType, double> probabilities = new()
|
||||||
|
{
|
||||||
|
{ CharacterActionType.UseItem, pItem },
|
||||||
|
{ CharacterActionType.PreCastSkill, pSkill },
|
||||||
|
{ CharacterActionType.NormalAttack, pAttack }
|
||||||
|
};
|
||||||
|
|
||||||
|
double maxProb = probabilities.Values.Max();
|
||||||
|
if (maxProb > 0)
|
||||||
|
{
|
||||||
|
CharacterActionType preferredType = probabilities.FirstOrDefault(kvp => kvp.Value == maxProb).Key;
|
||||||
|
|
||||||
|
// 如果最高概率超过阈值,优先考虑该类型
|
||||||
|
if (maxProb > 0.7)
|
||||||
|
{
|
||||||
|
return preferredType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态调整概率
|
||||||
|
private static void AdjustProbabilitiesBasedOnContext(ref double pUseItem, ref double pCastSkill, ref double pNormalAttack, Character character, List<Character> allEnemysInGame, List<Character> allTeammatesInGame)
|
||||||
|
{
|
||||||
|
// 基于角色状态调整
|
||||||
|
if (character.HP / character.MaxHP < 0.3 || allTeammatesInGame.Any(c => c.HP / c.MaxHP < 0.3))
|
||||||
|
{
|
||||||
|
// 低生命值时增加使用物品概率
|
||||||
|
if (pUseItem > 0) pUseItem *= 1.5;
|
||||||
|
if (pCastSkill > 0) pCastSkill *= 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基于敌人数量调整
|
||||||
|
int enemyCount = allEnemysInGame.Count;
|
||||||
|
if (enemyCount > 3)
|
||||||
|
{
|
||||||
|
// 敌人多时倾向于范围技能
|
||||||
|
if (pCastSkill > 0) pCastSkill *= 1.3;
|
||||||
|
}
|
||||||
|
else if (enemyCount == 1)
|
||||||
|
{
|
||||||
|
// 单个敌人时倾向于普通攻击
|
||||||
|
if (pNormalAttack > 0) pNormalAttack *= 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pUseItem > 0) pUseItem = Math.Max(0, pUseItem);
|
||||||
|
if (pCastSkill > 0) pCastSkill = Math.Max(0, pCastSkill);
|
||||||
|
if (pNormalAttack > 0) pNormalAttack = Math.Max(0, pNormalAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// / 归一化概率分布
|
||||||
|
private static double[] NormalizeProbabilities(double pUseItem, double pCastSkill, double pNormalAttack)
|
||||||
|
{
|
||||||
|
if (pUseItem <= 0 && pCastSkill <= 0 && pNormalAttack <= 0)
|
||||||
|
{
|
||||||
|
return [0, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
double sum = pUseItem + pCastSkill + pNormalAttack;
|
||||||
|
if (sum <= 0) return [0.33, 0.33, 0.34];
|
||||||
|
|
||||||
|
return [
|
||||||
|
pUseItem / sum,
|
||||||
|
pCastSkill / sum,
|
||||||
|
pNormalAttack / sum
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// 检查角色是否能进行普通攻击(基于状态)
|
// 检查角色是否能进行普通攻击(基于状态)
|
||||||
private static bool CanCharacterNormalAttack(Character character, DecisionPoints dp)
|
private static bool CanCharacterNormalAttack(Character character, DecisionPoints dp)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1283,7 +1283,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
}
|
}
|
||||||
if (isUp)
|
if (isUp)
|
||||||
{
|
{
|
||||||
Effect[] effects = [.. Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
e.OnOwnerLevelUp(this, Level);
|
e.OnOwnerLevelUp(this, Level);
|
||||||
@ -1312,7 +1312,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void OnAttributeChanged()
|
public void OnAttributeChanged()
|
||||||
{
|
{
|
||||||
List<Effect> effects = [.. Effects.Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnAttributeChanged(this);
|
effect.OnAttributeChanged(this);
|
||||||
@ -1447,41 +1447,8 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
||||||
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
||||||
}
|
}
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
|
||||||
List<string> shield = [];
|
builder.AppendLine(GetAttributeInfo(showGrowth).Trim());
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
|
||||||
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
|
||||||
if (Shield.TotalMix > 0) shield.Add($"混合:{Shield.TotalMix:0.##}");
|
|
||||||
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
|
||||||
double exMP = ExMP + ExMP2 + ExMP3;
|
|
||||||
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
|
|
||||||
double exATK = ExATK + ExATK2 + ExATK3;
|
|
||||||
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
|
|
||||||
double exDEF = ExDEF + ExDEF2 + ExDEF3;
|
|
||||||
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
|
|
||||||
builder.AppendLine(GetMagicResistanceInfo().Trim());
|
|
||||||
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($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
|
|
||||||
double exSTR = ExSTR + ExSTR2;
|
|
||||||
builder.AppendLine($"力量:{STR:0.##}" + (exSTR != 0 ? $" [{BaseSTR:0.##} {(exSTR >= 0 ? "+" : "-")} {Math.Abs(exSTR):0.##}]" : "") + (showGrowth ? $"({(STRGrowth >= 0 ? "+" : "-")}{Math.Abs(STRGrowth)}/Lv)" : "") + $"({STRExemption * 100:0.##}%)");
|
|
||||||
double exAGI = ExAGI + ExAGI2;
|
|
||||||
builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"({(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv)" : "") + $"({AGIExemption * 100:0.##}%)");
|
|
||||||
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)" : "") + $"({INTExemption * 100: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 * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"暴击率:{CritRate * 100:0.##}%");
|
|
||||||
builder.AppendLine($"暴击伤害:{CritDMG * 100:0.##}%");
|
|
||||||
builder.AppendLine($"闪避率:{EvadeRate * 100:0.##}%");
|
|
||||||
builder.AppendLine($"生命偷取:{Lifesteal * 100:0.##}%");
|
|
||||||
builder.AppendLine($"冷却缩减:{CDR * 100:0.##}%");
|
|
||||||
builder.AppendLine($"加速系数:{AccelerationCoefficient * 100:0.##}%");
|
|
||||||
builder.AppendLine($"物理穿透:{PhysicalPenetration * 100:0.##}%");
|
|
||||||
builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%");
|
|
||||||
builder.AppendLine($"魔法消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%");
|
|
||||||
builder.AppendLine($"能量消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%");
|
|
||||||
|
|
||||||
if (showMapRelated)
|
if (showMapRelated)
|
||||||
{
|
{
|
||||||
@ -1489,7 +1456,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
builder.AppendLine($"攻击距离:{ATR}");
|
builder.AppendLine($"攻击距离:{ATR}");
|
||||||
}
|
}
|
||||||
|
|
||||||
GetStatusInfo(builder);
|
builder.AppendLine(GetStatusInfo().Trim());
|
||||||
|
|
||||||
builder.AppendLine("== 普通攻击 ==");
|
builder.AppendLine("== 普通攻击 ==");
|
||||||
builder.Append(NormalAttack.ToString());
|
builder.Append(NormalAttack.ToString());
|
||||||
@ -1541,38 +1508,8 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
||||||
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
||||||
}
|
}
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
|
||||||
List<string> shield = [];
|
builder.AppendLine(GetSimpleAttributeInfo(showGrowth, showBasicOnly).Trim());
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
|
||||||
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
|
||||||
if (Shield.TotalMix > 0) shield.Add($"混合:{Shield.TotalMix:0.##}");
|
|
||||||
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
|
||||||
double exMP = ExMP + ExMP2 + ExMP3;
|
|
||||||
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
|
|
||||||
double exATK = ExATK + ExATK2 + ExATK3;
|
|
||||||
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
|
|
||||||
double exDEF = ExDEF + ExDEF2 + ExDEF3;
|
|
||||||
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
|
|
||||||
builder.AppendLine(GetMagicResistanceInfo().Trim());
|
|
||||||
if (showBasicOnly)
|
|
||||||
{
|
|
||||||
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}({CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)})");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
|
|
||||||
double exSTR = ExSTR + ExSTR2;
|
|
||||||
builder.AppendLine($"力量:{STR:0.##}" + (exSTR != 0 ? $" [{BaseSTR:0.##} {(exSTR >= 0 ? "+" : "-")} {Math.Abs(exSTR):0.##}]" : "") + (showGrowth ? $"({(STRGrowth >= 0 ? "+" : "-")}{Math.Abs(STRGrowth)}/Lv)" : "") + $"({STRExemption * 100:0.##}%)");
|
|
||||||
double exAGI = ExAGI + ExAGI2;
|
|
||||||
builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"({(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv)" : "") + $"({AGIExemption * 100:0.##}%)");
|
|
||||||
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)" : "") + $"({INTExemption * 100: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 * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
|
|
||||||
|
|
||||||
if (showMapRelated)
|
if (showMapRelated)
|
||||||
{
|
{
|
||||||
@ -1582,7 +1519,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
|
|
||||||
if (!showBasicOnly)
|
if (!showBasicOnly)
|
||||||
{
|
{
|
||||||
GetStatusInfo(builder);
|
builder.AppendLine(GetStatusInfo().Trim());
|
||||||
|
|
||||||
if (Skills.Count > 0)
|
if (Skills.Count > 0)
|
||||||
{
|
{
|
||||||
@ -1636,26 +1573,16 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
/// 获取战斗状态的信息
|
/// 获取战斗状态的信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hardnessTimes"></param>
|
/// <param name="hardnessTimes"></param>
|
||||||
|
/// <param name="simpleStatusBar"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetInBattleInfo(double hardnessTimes)
|
public string GetInBattleInfo(double hardnessTimes, bool simpleStatusBar = false)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
|
|
||||||
builder.AppendLine((HP == 0 ? "[ 死亡 ] " : "") + ToStringWithLevel());
|
builder.AppendLine((HP == 0 ? "[ 死亡 ] " : "") + ToStringWithLevel());
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
|
||||||
List<string> shield = [];
|
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
|
||||||
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
|
||||||
if (Shield.TotalMix > 0) shield.Add($"混合:{Shield.TotalMix:0.##}");
|
|
||||||
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
|
||||||
double exMP = ExMP + ExMP2 + ExMP3;
|
|
||||||
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
|
|
||||||
double exATK = ExATK + ExATK2 + ExATK3;
|
|
||||||
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.##}]" : ""));
|
|
||||||
|
|
||||||
GetStatusInfo(builder);
|
builder.AppendLine(GetSimpleAttributeInfo(false, true).Trim());
|
||||||
|
builder.AppendLine(GetStatusInfo().Trim());
|
||||||
|
|
||||||
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
|
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
|
||||||
|
|
||||||
@ -1663,49 +1590,22 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
if (effects.Length > 0)
|
if (effects.Length > 0)
|
||||||
{
|
{
|
||||||
builder.AppendLine("== 状态栏 ==");
|
builder.AppendLine("== 状态栏 ==");
|
||||||
foreach (Effect effect in effects)
|
if (simpleStatusBar)
|
||||||
{
|
{
|
||||||
builder.AppendLine(effect.ToString());
|
builder.Append(string.Join(",", effects.Select(e => e.Name)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Effect effect in effects)
|
||||||
|
{
|
||||||
|
builder.AppendLine(effect.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.ToString().Trim();
|
return builder.ToString().Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取战斗状态的信息(简略版)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hardnessTimes"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string GetSimpleInBattleInfo(double hardnessTimes)
|
|
||||||
{
|
|
||||||
StringBuilder builder = new();
|
|
||||||
|
|
||||||
builder.AppendLine((HP == 0 ? "[ 死亡 ] " : "") + ToStringWithLevel());
|
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
|
||||||
List<string> shield = [];
|
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
|
||||||
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
|
||||||
if (Shield.TotalMix > 0) shield.Add($"混合:{Shield.TotalMix:0.##}");
|
|
||||||
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
|
||||||
double exMP = ExMP + ExMP2 + ExMP3;
|
|
||||||
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
|
|
||||||
double exATK = ExATK + ExATK2 + ExATK3;
|
|
||||||
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($"硬直时间:{hardnessTimes:0.##}");
|
|
||||||
|
|
||||||
Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
|
|
||||||
if (effects.Length > 0)
|
|
||||||
{
|
|
||||||
builder.AppendLine("== 状态栏 ==");
|
|
||||||
builder.Append(string.Join(",", effects.Select(e => e.Name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取角色的技能信息
|
/// 获取角色的技能信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1716,7 +1616,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
|
|
||||||
builder.AppendLine((HP == 0 ? "[ 死亡 ] " : "") + (showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()));
|
builder.AppendLine((HP == 0 ? "[ 死亡 ] " : "") + (showUser ? ToStringWithLevel() : ToStringWithLevelWithOutUser()));
|
||||||
|
|
||||||
GetStatusInfo(builder);
|
builder.AppendLine(GetStatusInfo().Trim());
|
||||||
|
|
||||||
builder.AppendLine("== 普通攻击 ==");
|
builder.AppendLine("== 普通攻击 ==");
|
||||||
builder.Append(NormalAttack.ToString());
|
builder.Append(NormalAttack.ToString());
|
||||||
@ -1757,6 +1657,35 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
builder.AppendLine($"等级:{Level} / {GameplayEquilibriumConstant.MaxLevel}(突破进度:{LevelBreak + 1} / {GameplayEquilibriumConstant.LevelBreakList.Count})");
|
||||||
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
builder.AppendLine($"经验值:{EXP:0.##}{(Level != GameplayEquilibriumConstant.MaxLevel && GameplayEquilibriumConstant.EXPUpperLimit.TryGetValue(Level, out double need) ? " / " + need : "")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.AppendLine(GetAttributeInfo(showGrowth).Trim());
|
||||||
|
|
||||||
|
if (showMapRelated)
|
||||||
|
{
|
||||||
|
builder.AppendLine($"移动距离:{MOV}");
|
||||||
|
builder.AppendLine($"攻击距离:{ATR}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EquipSlot.Any())
|
||||||
|
{
|
||||||
|
builder.AppendLine(GetEquipSlotInfo().Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Items.Count > 0)
|
||||||
|
{
|
||||||
|
builder.AppendLine(GetBackpackItemsInfo().Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取角色属性和能力值信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetAttributeInfo(bool showGrowth = true)
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
double exHP = ExHP + ExHP2 + ExHP3;
|
||||||
List<string> shield = [];
|
List<string> shield = [];
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
||||||
@ -1792,28 +1721,58 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%");
|
builder.AppendLine($"魔法穿透:{MagicalPenetration * 100:0.##}%");
|
||||||
builder.AppendLine($"魔法消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%");
|
builder.AppendLine($"魔法消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastMPReduce * 100:0.##}%");
|
||||||
builder.AppendLine($"能量消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%");
|
builder.AppendLine($"能量消耗减少:{INT * GameplayEquilibriumConstant.INTtoCastEPReduce * 100:0.##}%");
|
||||||
|
|
||||||
if (showMapRelated)
|
|
||||||
{
|
|
||||||
builder.AppendLine($"移动距离:{MOV}");
|
|
||||||
builder.AppendLine($"攻击距离:{ATR}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EquipSlot.Any())
|
|
||||||
{
|
|
||||||
builder.AppendLine(GetEquipSlotInfo().Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Items.Count > 0)
|
|
||||||
{
|
|
||||||
builder.AppendLine(GetBackpackItemsInfo().Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetStatusInfo(StringBuilder builder)
|
/// <summary>
|
||||||
|
/// 获取角色属性和能力值的简略版信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetSimpleAttributeInfo(bool showGrowth = true, bool showBasicOnly = false)
|
||||||
{
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
double exHP = ExHP + ExHP2 + ExHP3;
|
||||||
|
List<string> shield = [];
|
||||||
|
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
||||||
|
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
||||||
|
if (Shield.TotalMix > 0) shield.Add($"混合:{Shield.TotalMix:0.##}");
|
||||||
|
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
||||||
|
double exMP = ExMP + ExMP2 + ExMP3;
|
||||||
|
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
||||||
|
builder.AppendLine($"能量值:{EP:0.##} / {GameplayEquilibriumConstant.MaxEP:0.##}");
|
||||||
|
double exATK = ExATK + ExATK2 + ExATK3;
|
||||||
|
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
|
||||||
|
double exDEF = ExDEF + ExDEF2 + ExDEF3;
|
||||||
|
builder.AppendLine($"物理护甲:{DEF:0.##}" + (exDEF != 0 ? $" [{BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({PDR * 100:0.##}%)");
|
||||||
|
builder.AppendLine(GetMagicResistanceInfo().Trim());
|
||||||
|
if (showBasicOnly)
|
||||||
|
{
|
||||||
|
builder.AppendLine($"核心属性:{PrimaryAttributeValue:0.##}({CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)})");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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($"核心属性:{CharacterSet.GetPrimaryAttributeName(PrimaryAttribute)}");
|
||||||
|
double exSTR = ExSTR + ExSTR2;
|
||||||
|
builder.AppendLine($"力量:{STR:0.##}" + (exSTR != 0 ? $" [{BaseSTR:0.##} {(exSTR >= 0 ? "+" : "-")} {Math.Abs(exSTR):0.##}]" : "") + (showGrowth ? $"({(STRGrowth >= 0 ? "+" : "-")}{Math.Abs(STRGrowth)}/Lv)" : "") + $"({STRExemption * 100:0.##}%)");
|
||||||
|
double exAGI = ExAGI + ExAGI2;
|
||||||
|
builder.AppendLine($"敏捷:{AGI:0.##}" + (exAGI != 0 ? $" [{BaseAGI:0.##} {(exAGI >= 0 ? "+" : "-")} {Math.Abs(exAGI):0.##}]" : "") + (showGrowth ? $"({(AGIGrowth >= 0 ? "+" : "-")}{Math.Abs(AGIGrowth)}/Lv)" : "") + $"({AGIExemption * 100:0.##}%)");
|
||||||
|
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)" : "") + $"({INTExemption * 100: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 * GameplayEquilibriumConstant.INTtoMRFactor:0.##} {(ExMR >= 0 ? "+" : "-")} {Math.Abs(ExMR):0.##}]" : ""));
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取角色状态信息
|
||||||
|
/// </summary>
|
||||||
|
public string GetStatusInfo()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
|
||||||
if (CharacterState != CharacterState.Actionable)
|
if (CharacterState != CharacterState.Actionable)
|
||||||
{
|
{
|
||||||
builder.AppendLine(CharacterSet.GetCharacterState(CharacterState));
|
builder.AppendLine(CharacterSet.GetCharacterState(CharacterState));
|
||||||
@ -1848,6 +1807,8 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
builder.AppendLine("角色是不可选中的");
|
builder.AppendLine("角色是不可选中的");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -2134,7 +2095,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
List<Skill> skills = [.. Skills];
|
List<Skill> skills = [.. Skills];
|
||||||
List<Item> items = [.. Items];
|
List<Item> items = [.. Items];
|
||||||
Character c = original.Copy();
|
Character c = original.Copy();
|
||||||
List<Effect> effects = [.. Effects];
|
List<Effect> effects = [.. Effects.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
e.OnEffectLost(this);
|
e.OnEffectLost(this);
|
||||||
|
|||||||
@ -292,8 +292,9 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
/// 获取战斗状态的信息
|
/// 获取战斗状态的信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hardnessTimes"></param>
|
/// <param name="hardnessTimes"></param>
|
||||||
|
/// <param name="simpleStatusBar"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public new string GetInBattleInfo(double hardnessTimes)
|
public new string GetInBattleInfo(double hardnessTimes, bool simpleStatusBar = false)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
|
|
||||||
@ -339,38 +340,6 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取战斗状态的信息(简略版)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hardnessTimes"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public new string GetSimpleInBattleInfo(double hardnessTimes)
|
|
||||||
{
|
|
||||||
StringBuilder builder = new();
|
|
||||||
|
|
||||||
builder.AppendLine(ToStringWithLevel());
|
|
||||||
double exHP = ExHP + ExHP2 + ExHP3;
|
|
||||||
List<string> shield = [];
|
|
||||||
if (Shield.TotalPhysical > 0) shield.Add($"物理:{Shield.TotalPhysical:0.##}");
|
|
||||||
if (Shield.TotalMagical > 0) shield.Add($"魔法:{Shield.TotalMagical:0.##}");
|
|
||||||
if (Shield.Mix > 0) shield.Add($"混合:{Shield.Mix:0.##}");
|
|
||||||
builder.AppendLine($"生命值:{HP:0.##} / {MaxHP:0.##}" + (exHP != 0 ? $" [{BaseHP:0.##} {(exHP >= 0 ? "+" : "-")} {Math.Abs(exHP):0.##}]" : "") + (shield.Count > 0 ? $"({string.Join(",", shield)})" : ""));
|
|
||||||
double exMP = ExMP + ExMP2 + ExMP3;
|
|
||||||
builder.AppendLine($"魔法值:{MP:0.##} / {MaxMP:0.##}" + (exMP != 0 ? $" [{BaseMP:0.##} {(exMP >= 0 ? "+" : "-")} {Math.Abs(exMP):0.##}]" : ""));
|
|
||||||
double exATK = ExATK + ExATK2 + ExATK3;
|
|
||||||
builder.AppendLine($"攻击力:{ATK:0.##}" + (exATK != 0 ? $" [{BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : ""));
|
|
||||||
builder.AppendLine($"硬直时间:{hardnessTimes:0.##}");
|
|
||||||
|
|
||||||
Effect[] effects = [.. Effects.Where(e => e.ShowInStatusBar)];
|
|
||||||
if (effects.Length > 0)
|
|
||||||
{
|
|
||||||
builder.AppendLine("== 状态栏 ==");
|
|
||||||
builder.Append(string.Join(",", effects.Select(e => e.Name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取单位的技能信息
|
/// 获取单位的技能信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -252,7 +252,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.IsInEffect)];
|
List<Effect> effects = [.. Character.Effects.Where(e => e.Skill == skill && e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
Character.Effects.Remove(e);
|
Character.Effects.Remove(e);
|
||||||
|
|||||||
@ -18,6 +18,12 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Skill Skill { get; }
|
public Skill Skill { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 特效触发优先级
|
||||||
|
/// 越大优先级越高;默认值为 0,在状态栏(<see cref="Character.Effects"/>)中使用默认哈希排序。
|
||||||
|
/// </summary>
|
||||||
|
public int Priority { get; set; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 特殊效果类型<para/>
|
/// 特殊效果类型<para/>
|
||||||
/// 注意:如果技能特效没有原生施加控制效果,请始终保持此属性为 <see cref="EffectType.None"/>。
|
/// 注意:如果技能特效没有原生施加控制效果,请始终保持此属性为 <see cref="EffectType.None"/>。
|
||||||
@ -1267,7 +1273,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Effect[] effects = [.. target.Effects.Where(e => e.ShowInStatusBar)];
|
Effect[] effects = [.. target.Effects.Where(e => e.ShowInStatusBar).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.OnEffectIsBeingDispelled(dispeller, target, this, isEnemy))
|
if (effect.OnEffectIsBeingDispelled(dispeller, target, this, isEnemy))
|
||||||
|
|||||||
@ -408,7 +408,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
}
|
}
|
||||||
if (Level > 0 && Character != null)
|
if (Level > 0 && Character != null)
|
||||||
{
|
{
|
||||||
Effect[] effects = [.. Character.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. Character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
e.OnSkillLevelUp(Character, Level);
|
e.OnSkillLevelUp(Character, Level);
|
||||||
@ -474,7 +474,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
|
|
||||||
foreach (Character character in enemys)
|
foreach (Character character in enemys)
|
||||||
{
|
{
|
||||||
IEnumerable<Effect> effects = Effects.Where(e => e.IsInEffect);
|
IEnumerable<Effect> effects = Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority);
|
||||||
if (CanSelectEnemy && ((character.ImmuneType & checkType) == ImmuneType.None ||
|
if (CanSelectEnemy && ((character.ImmuneType & checkType) == ImmuneType.None ||
|
||||||
effects.Any(e => e.IgnoreImmune == ImmuneType.All || e.IgnoreImmune == ImmuneType.Skilled || (IsMagic && e.IgnoreImmune == ImmuneType.Magical))))
|
effects.Any(e => e.IgnoreImmune == ImmuneType.All || e.IgnoreImmune == ImmuneType.Skilled || (IsMagic && e.IgnoreImmune == ImmuneType.Magical))))
|
||||||
{
|
{
|
||||||
@ -609,7 +609,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
|
|
||||||
if (allEnemys.Contains(character))
|
if (allEnemys.Contains(character))
|
||||||
{
|
{
|
||||||
IEnumerable<Effect> effects = Effects.Where(e => e.IsInEffect);
|
IEnumerable<Effect> effects = Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority);
|
||||||
if (CanSelectEnemy && ((AllowSelectDead && character.HP == 0) || (!AllowSelectDead && character.HP > 0)) &&
|
if (CanSelectEnemy && ((AllowSelectDead && character.HP == 0) || (!AllowSelectDead && character.HP > 0)) &&
|
||||||
((character.ImmuneType & checkType) == ImmuneType.None || effects.Any(e => e.IgnoreImmune == ImmuneType.All || e.IgnoreImmune == ImmuneType.Skilled || (IsMagic && e.IgnoreImmune == ImmuneType.Magical))))
|
((character.ImmuneType & checkType) == ImmuneType.None || effects.Any(e => e.IgnoreImmune == ImmuneType.All || e.IgnoreImmune == ImmuneType.Skilled || (IsMagic && e.IgnoreImmune == ImmuneType.Magical))))
|
||||||
{
|
{
|
||||||
@ -725,7 +725,7 @@ namespace Milimoe.FunGame.Core.Entity
|
|||||||
Character[] characters = [caster, .. targets];
|
Character[] characters = [caster, .. targets];
|
||||||
foreach (Character target in characters)
|
foreach (Character target in characters)
|
||||||
{
|
{
|
||||||
Effect[] effects = [.. target.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. target.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
e.GamingQueue = GamingQueue;
|
e.GamingQueue = GamingQueue;
|
||||||
|
|||||||
@ -979,7 +979,7 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon
|
|||||||
|
|
||||||
foreach (Grid grid in Grids.Values)
|
foreach (Grid grid in Grids.Values)
|
||||||
{
|
{
|
||||||
List<Effect> effects = [.. grid.Effects];
|
List<Effect> effects = [.. grid.Effects.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.Durative)
|
if (effect.Durative)
|
||||||
|
|||||||
@ -14,6 +14,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public List<Character> Targets { get; set; } = [];
|
public List<Character> Targets { get; set; } = [];
|
||||||
public List<Grid> TargetGrids { get; set; } = [];
|
public List<Grid> TargetGrids { get; set; } = [];
|
||||||
public double Score { get; set; } = 0;
|
public double Score { get; set; } = 0;
|
||||||
|
public double ProbabilityWeight { get; set; } = 0;
|
||||||
public bool IsPureMove { get; set; } = false;
|
public bool IsPureMove { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -712,7 +712,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
// 触发游戏开始事件
|
// 触发游戏开始事件
|
||||||
OnGameStartEvent();
|
OnGameStartEvent();
|
||||||
Effect[] effects = [.. _queue.SelectMany(c => c.Effects).Where(e => e.IsInEffect)];
|
Effect[] effects = [.. _queue.SelectMany(c => c.Effects).Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnGameStart();
|
effect.OnGameStart();
|
||||||
@ -795,7 +795,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
double reallyReHP = needHP >= recoveryHP ? recoveryHP : needHP;
|
double reallyReHP = needHP >= recoveryHP ? recoveryHP : needHP;
|
||||||
double reallyReMP = needMP >= recoveryMP ? recoveryMP : needMP;
|
double reallyReMP = needMP >= recoveryMP ? recoveryMP : needMP;
|
||||||
bool allowRecovery = true;
|
bool allowRecovery = true;
|
||||||
Effect[] effects = [.. character.Effects];
|
Effect[] effects = [.. character.Effects.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeApplyRecoveryAtTimeLapsing(character, ref reallyReHP, ref reallyReMP))
|
if (!effect.BeforeApplyRecoveryAtTimeLapsing(character, ref reallyReHP, ref reallyReMP))
|
||||||
@ -847,7 +847,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
_map?.OnTimeElapsed(timeToReduce);
|
_map?.OnTimeElapsed(timeToReduce);
|
||||||
|
|
||||||
// 移除到时间的特效
|
// 移除到时间的特效
|
||||||
effects = [.. character.Effects];
|
effects = [.. character.Effects.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!character.Shield.ShieldOfEffects.ContainsKey(effect))
|
if (!character.Shield.ShieldOfEffects.ContainsKey(effect))
|
||||||
@ -919,7 +919,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果特效具备临时驱散或者持续性驱散的功能
|
// 如果特效具备临时驱散或者持续性驱散的功能
|
||||||
effects = [.. character.Effects.Where(e => e.Source != null && (e.EffectType == EffectType.WeakDispelling || e.EffectType == EffectType.StrongDispelling))];
|
effects = [.. character.Effects.Where(e => e.Source != null && (e.EffectType == EffectType.WeakDispelling || e.EffectType == EffectType.StrongDispelling)).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.Source is null) continue;
|
if (effect.Source is null) continue;
|
||||||
@ -1025,7 +1025,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
skillTurnStart.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
|
skillTurnStart.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
|
effect.OnTurnStart(character, selectableEnemys, selectableTeammates, skills, items);
|
||||||
@ -1128,7 +1128,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
// 行动开始前,可以修改可选取的角色列表
|
// 行动开始前,可以修改可选取的角色列表
|
||||||
Dictionary<Character, int> continuousKillingTemp = new(_continuousKilling);
|
Dictionary<Character, int> continuousKillingTemp = new(_continuousKilling);
|
||||||
Dictionary<Character, int> earnedMoneyTemp = new(_earnedMoney);
|
Dictionary<Character, int> earnedMoneyTemp = new(_earnedMoney);
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterSelectListBeforeAction(character, enemys, teammates, skills, continuousKillingTemp, earnedMoneyTemp);
|
effect.AlterSelectListBeforeAction(character, enemys, teammates, skills, continuousKillingTemp, earnedMoneyTemp);
|
||||||
@ -1159,7 +1159,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill)
|
if (character.CharacterState != CharacterState.Casting && character.CharacterState != CharacterState.PreCastSuperSkill)
|
||||||
{
|
{
|
||||||
CharacterActionType actionTypeTemp = CharacterActionType.None;
|
CharacterActionType actionTypeTemp = CharacterActionType.None;
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
bool force = false;
|
bool force = false;
|
||||||
@ -1268,7 +1268,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
List<Character> allEnemysInGame = [.. allEnemys.Where(canAttackGridsByStartGrid.Union(canCastGridsByStartGrid).SelectMany(g => g.Characters).Contains)];
|
List<Character> allEnemysInGame = [.. allEnemys.Where(canAttackGridsByStartGrid.Union(canCastGridsByStartGrid).SelectMany(g => g.Characters).Contains)];
|
||||||
List<Character> allTeammatesInGame = [.. allTeammates.Where(canAttackGridsByStartGrid.Union(canCastGridsByStartGrid).SelectMany(g => g.Characters).Contains)];
|
List<Character> allTeammatesInGame = [.. allTeammates.Where(canAttackGridsByStartGrid.Union(canCastGridsByStartGrid).SelectMany(g => g.Characters).Contains)];
|
||||||
|
|
||||||
aiDecision = ai.DecideAIAction(character, dp, startGrid, canMoveGrids, skills, items, allEnemys, allTeammates, enemys, teammates);
|
aiDecision = ai.DecideAIAction(character, dp, startGrid, canMoveGrids, skills, items, allEnemys, allTeammates, enemys, teammates, pUseItem, pCastSkill, pNormalAttack);
|
||||||
type = aiDecision.ActionType;
|
type = aiDecision.ActionType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1307,7 +1307,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
int costDP = dp.GetActionPointCost(type);
|
int costDP = dp.GetActionPointCost(type);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCharacterActionStart(character, dp, type);
|
effect.OnCharacterActionStart(character, dp, type);
|
||||||
@ -1396,14 +1396,14 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
character.NormalAttack.Attack(this, character, null, targets);
|
character.NormalAttack.Attack(this, character, null, targets);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterNormalAttack(character, character.NormalAttack, targets);
|
effect.AfterCharacterNormalAttack(character, character.NormalAttack, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
baseTime += character.NormalAttack.RealHardnessTime;
|
baseTime += character.NormalAttack.RealHardnessTime;
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterHardnessTimeAfterNormalAttack(character, ref baseTime, ref isCheckProtected);
|
effect.AlterHardnessTimeAfterNormalAttack(character, ref baseTime, ref isCheckProtected);
|
||||||
@ -1493,7 +1493,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
isCheckProtected = false;
|
isCheckProtected = false;
|
||||||
skill.OnSkillCasting(this, character, targets, grids);
|
skill.OnSkillCasting(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterStartCasting(character, skill, targets);
|
effect.AfterCharacterStartCasting(character, skill, targets);
|
||||||
@ -1568,7 +1568,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasting(this, character, targets, grids);
|
skill.OnSkillCasting(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterStartCasting(character, skill, targets);
|
effect.AfterCharacterStartCasting(character, skill, targets);
|
||||||
@ -1587,13 +1587,13 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasted(this, character, targets, grids);
|
skill.OnSkillCasted(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterCastSkill(character, skill, targets);
|
effect.AfterCharacterCastSkill(character, skill, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
||||||
@ -1663,13 +1663,13 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasted(this, character, targets, grids);
|
skill.OnSkillCasted(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterCastSkill(character, skill, targets);
|
effect.AfterCharacterCastSkill(character, skill, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
||||||
@ -1735,13 +1735,13 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasted(this, character, targets, grids);
|
skill.OnSkillCasted(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterCastSkill(character, skill, targets);
|
effect.AfterCharacterCastSkill(character, skill, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
||||||
@ -1815,7 +1815,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
LastRound.Items[CharacterActionType.UseItem] = item;
|
LastRound.Items[CharacterActionType.UseItem] = item;
|
||||||
decided = true;
|
decided = true;
|
||||||
baseTime += skill.RealHardnessTime > 0 ? skill.RealHardnessTime : 5;
|
baseTime += skill.RealHardnessTime > 0 ? skill.RealHardnessTime : 5;
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
effect.AlterHardnessTimeAfterCastSkill(character, skill, ref baseTime, ref isCheckProtected);
|
||||||
@ -1864,7 +1864,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
OnCharacterActionTakenEvent(character, dp, type, LastRound);
|
OnCharacterActionTakenEvent(character, dp, type, LastRound);
|
||||||
|
|
||||||
effects = [.. _queue.Union([character]).SelectMany(c => c.Effects).Where(e => e.IsInEffect).Distinct()];
|
effects = [.. _queue.Union([character]).SelectMany(c => c.Effects).Where(e => e.IsInEffect).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCharacterActionTaken(character, dp, type);
|
effect.OnCharacterActionTaken(character, dp, type);
|
||||||
@ -1888,7 +1888,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
AfterCharacterDecision(character, dp);
|
AfterCharacterDecision(character, dp);
|
||||||
OnCharacterDecisionCompletedEvent(character, dp, LastRound);
|
OnCharacterDecisionCompletedEvent(character, dp, LastRound);
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCharacterDecisionCompleted(character, dp);
|
effect.OnCharacterDecisionCompleted(character, dp);
|
||||||
@ -1928,7 +1928,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
LastRound.HardnessTime = newHardnessTime;
|
LastRound.HardnessTime = newHardnessTime;
|
||||||
OnQueueUpdatedEvent(_queue, character, dp, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。");
|
OnQueueUpdatedEvent(_queue, character, dp, newHardnessTime, QueueUpdatedReason.Action, "设置角色行动后的硬直时间。");
|
||||||
|
|
||||||
effects = [.. character.Effects];
|
effects = [.. character.Effects.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.IsInEffect)
|
if (effect.IsInEffect)
|
||||||
@ -1959,9 +1959,6 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
// 清空临时决策点
|
// 清空临时决策点
|
||||||
dp.ClearTempActionQuota();
|
dp.ClearTempActionQuota();
|
||||||
|
|
||||||
// 有人想要插队吗?
|
|
||||||
WillPreCastSuperSkill();
|
|
||||||
|
|
||||||
// 回合结束事件
|
// 回合结束事件
|
||||||
OnTurnEndEvent(character, dp);
|
OnTurnEndEvent(character, dp);
|
||||||
|
|
||||||
@ -1969,6 +1966,10 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
WriteLine("");
|
WriteLine("");
|
||||||
_isInRound = false;
|
_isInRound = false;
|
||||||
|
|
||||||
|
// 有人想要插队吗?
|
||||||
|
WillPreCastSuperSkill();
|
||||||
|
|
||||||
return _isGameEnd;
|
return _isGameEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2126,7 +2127,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
// 真实伤害跳过伤害加成区间
|
// 真实伤害跳过伤害加成区间
|
||||||
if (damageType != DamageType.True)
|
if (damageType != DamageType.True)
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, damageType, magicType, damageResult, ref isEvaded, totalDamageBonus);
|
double damageBonus = effect.AlterActualDamageAfterCalculation(actor, enemy, damage, isNormalAttack, damageType, magicType, damageResult, ref isEvaded, totalDamageBonus);
|
||||||
@ -2140,7 +2141,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.BeforeApplyTrueDamage(actor, enemy, damage, isNormalAttack, damageResult))
|
if (effect.BeforeApplyTrueDamage(actor, enemy, damage, isNormalAttack, damageResult))
|
||||||
@ -2188,7 +2189,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
ignore = true;
|
ignore = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, damageType, magicType, damage))
|
if (!effect.OnDamageImmuneCheck(actor, enemy, isNormalAttack, damageType, magicType, damage))
|
||||||
@ -2227,7 +2228,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
// 在护盾结算前,特效可以有自己的逻辑
|
// 在护盾结算前,特效可以有自己的逻辑
|
||||||
bool change = false;
|
bool change = false;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
double damageReduce = 0;
|
double damageReduce = 0;
|
||||||
@ -2248,7 +2249,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
double remain = actualDamage;
|
double remain = actualDamage;
|
||||||
|
|
||||||
// 检查特效护盾
|
// 检查特效护盾
|
||||||
effects = [.. enemy.Shield.ShieldOfEffects.Keys];
|
effects = [.. enemy.Shield.ShieldOfEffects.Keys.OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
ShieldOfEffect soe = enemy.Shield.ShieldOfEffects[effect];
|
ShieldOfEffect soe = enemy.Shield.ShieldOfEffects[effect];
|
||||||
@ -2277,7 +2278,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {effectShield:0.##} 点{damageTypeString},护盾已破碎!");
|
WriteLine($"[ {enemy} ] 发动了 [ {effect.Skill.Name} ] 的护盾效果,抵消了 {effectShield:0.##} 点{damageTypeString},护盾已破碎!");
|
||||||
remain -= effectShield;
|
remain -= effectShield;
|
||||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect2 in effects2)
|
foreach (Effect effect2 in effects2)
|
||||||
{
|
{
|
||||||
if (!effect2.OnShieldBroken(enemy, actor, effect, remain))
|
if (!effect2.OnShieldBroken(enemy, actor, effect, remain))
|
||||||
@ -2289,7 +2290,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
if (remain <= 0)
|
if (remain <= 0)
|
||||||
{
|
{
|
||||||
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
Effect[] effects2 = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect2 in effects2)
|
foreach (Effect effect2 in effects2)
|
||||||
{
|
{
|
||||||
effect2.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Effect);
|
effect2.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Effect);
|
||||||
@ -2315,7 +2316,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
WriteLine($"[ {enemy} ] 的{shieldTypeString}护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
||||||
enemy.Shield[isMagicDamage, magicType] -= remain;
|
enemy.Shield[isMagicDamage, magicType] -= remain;
|
||||||
remain = 0;
|
remain = 0;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, shieldType);
|
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, shieldType);
|
||||||
@ -2328,7 +2329,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
enemy.Shield[isMagicDamage, magicType] = 0;
|
enemy.Shield[isMagicDamage, magicType] = 0;
|
||||||
if (isMagicDamage && enemy.Shield.TotalMagical <= 0 || !isMagicDamage && enemy.Shield.TotalPhysical <= 0)
|
if (isMagicDamage && enemy.Shield.TotalMagical <= 0 || !isMagicDamage && enemy.Shield.TotalPhysical <= 0)
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.OnShieldBroken(enemy, actor, shieldType, remain))
|
if (!effect.OnShieldBroken(enemy, actor, shieldType, remain))
|
||||||
@ -2351,7 +2352,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {remain:0.##} 点{damageTypeString}!");
|
||||||
enemy.Shield.Mix -= remain;
|
enemy.Shield.Mix -= remain;
|
||||||
remain = 0;
|
remain = 0;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Mix);
|
effect.OnShieldNeutralizeDamage(enemy, actor, damageType, magicType, damage, ShieldType.Mix);
|
||||||
@ -2362,7 +2363,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {enemy.Shield.TotalMix:0.##} 点{damageTypeString}并破碎!");
|
WriteLine($"[ {enemy} ] 的混合护盾抵消了 {enemy.Shield.TotalMix:0.##} 点{damageTypeString}并破碎!");
|
||||||
remain -= enemy.Shield.TotalMix;
|
remain -= enemy.Shield.TotalMix;
|
||||||
enemy.Shield.Mix = 0;
|
enemy.Shield.Mix = 0;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.OnShieldBroken(enemy, actor, ShieldType.Mix, remain))
|
if (!effect.OnShieldBroken(enemy, actor, ShieldType.Mix, remain))
|
||||||
@ -2397,7 +2398,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
options.ActualDamage = actualDamage;
|
options.ActualDamage = actualDamage;
|
||||||
enemy.HP -= actualDamage;
|
enemy.HP -= actualDamage;
|
||||||
string strDamageMessage = $"[ {enemy} ] 受到了 {actualDamage:0.##} 点{damageTypeString}!{shieldMsg}";
|
string strDamageMessage = $"[ {enemy} ] 受到了 {actualDamage:0.##} 点{damageTypeString}!{shieldMsg}";
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnApplyDamage(enemy, actor, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult, shieldMsg, ref strDamageMessage);
|
effect.OnApplyDamage(enemy, actor, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult, shieldMsg, ref strDamageMessage);
|
||||||
@ -2425,7 +2426,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
// 生命偷取
|
// 生命偷取
|
||||||
double steal = actualDamage * actor.Lifesteal;
|
double steal = actualDamage * actor.Lifesteal;
|
||||||
bool allowSteal = true;
|
bool allowSteal = true;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeLifesteal(actor, enemy, damage, steal))
|
if (!effect.BeforeLifesteal(actor, enemy, damage, steal))
|
||||||
@ -2436,7 +2437,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (allowSteal)
|
if (allowSteal)
|
||||||
{
|
{
|
||||||
HealToTarget(actor, actor, steal, false, true);
|
HealToTarget(actor, actor, steal, false, true);
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterLifesteal(actor, enemy, damage, steal);
|
effect.AfterLifesteal(actor, enemy, damage, steal);
|
||||||
@ -2447,7 +2448,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
double ep = GetEP(actualDamage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax);
|
double ep = GetEP(actualDamage, GameplayEquilibriumConstant.DamageGetEPFactor, GameplayEquilibriumConstant.DamageGetEPMax);
|
||||||
if (ep > 0)
|
if (ep > 0)
|
||||||
{
|
{
|
||||||
effects = [.. actor.Effects.Where(e => e.IsInEffect)];
|
effects = [.. actor.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterEPAfterDamage(actor, ref ep);
|
effect.AlterEPAfterDamage(actor, ref ep);
|
||||||
@ -2457,7 +2458,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
ep = GetEP(actualDamage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax);
|
ep = GetEP(actualDamage, GameplayEquilibriumConstant.TakenDamageGetEPFactor, GameplayEquilibriumConstant.TakenDamageGetEPMax);
|
||||||
if (ep > 0)
|
if (ep > 0)
|
||||||
{
|
{
|
||||||
effects = [.. enemy.Effects.Where(e => e.IsInEffect)];
|
effects = [.. enemy.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterEPAfterGetDamage(enemy, ref ep);
|
effect.AlterEPAfterGetDamage(enemy, ref ep);
|
||||||
@ -2497,7 +2498,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
if (options.TriggerEffects)
|
if (options.TriggerEffects)
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterDamageCalculation(actor, enemy, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult);
|
effect.AfterDamageCalculation(actor, enemy, damage, actualDamage, isNormalAttack, damageType, magicType, damageResult);
|
||||||
@ -2761,7 +2762,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool allowHealing = true;
|
bool allowHealing = true;
|
||||||
List<Effect> effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeHealToTarget(actor, target, heal, canRespawn))
|
if (!effect.BeforeHealToTarget(actor, target, heal, canRespawn))
|
||||||
@ -2782,7 +2783,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (triggerEffects)
|
if (triggerEffects)
|
||||||
{
|
{
|
||||||
Dictionary<Effect, double> totalHealBonus = [];
|
Dictionary<Effect, double> totalHealBonus = [];
|
||||||
effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.IsInEffect)];
|
effects = [.. actor.Effects.Union(target.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
bool changeCanRespawn = false;
|
bool changeCanRespawn = false;
|
||||||
@ -2971,7 +2972,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public void DealWithCharacterDied(Character killer, Character death, Character[] assists)
|
public void DealWithCharacterDied(Character killer, Character death, Character[] assists)
|
||||||
{
|
{
|
||||||
// 给所有角色的特效广播角色死亡结算
|
// 给所有角色的特效广播角色死亡结算
|
||||||
List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Union(killer.Effects).Distinct()];
|
List<Effect> effects = [.. _queue.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Union(killer.Effects).Distinct().OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterDeathCalculation(death, death.Master != null, killer, _continuousKilling, _earnedMoney, assists);
|
effect.AfterDeathCalculation(death, death.Master != null, killer, _continuousKilling, _earnedMoney, assists);
|
||||||
@ -3084,7 +3085,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasting(this, character, targets, grids);
|
skill.OnSkillCasting(this, character, targets, grids);
|
||||||
|
|
||||||
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterStartCasting(character, skill, targets);
|
effect.AfterCharacterStartCasting(character, skill, targets);
|
||||||
@ -3119,13 +3120,13 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
skill.OnSkillCasted(this, character, targets, grids);
|
skill.OnSkillCasted(this, character, targets, grids);
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterCastSkill(character, skill, targets);
|
effect.AfterCharacterCastSkill(character, skill, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterUseItem(character, item, skill, targets);
|
effect.AfterCharacterUseItem(character, item, skill, targets);
|
||||||
@ -3234,7 +3235,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Grid SelectTargetGrid(Character character, List<Character> enemys, List<Character> teammates, GameMap map, List<Grid> moveRange)
|
public Grid SelectTargetGrid(Character character, List<Character> enemys, List<Character> teammates, GameMap map, List<Grid> moveRange)
|
||||||
{
|
{
|
||||||
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.BeforeSelectTargetGrid(character, enemys, teammates, map, moveRange);
|
effect.BeforeSelectTargetGrid(character, enemys, teammates, map, moveRange);
|
||||||
@ -3265,7 +3266,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange)
|
public List<Character> SelectTargets(Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange)
|
||||||
{
|
{
|
||||||
List<Effect> effects = [.. caster.Effects.Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. caster.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterSelectListBeforeSelection(caster, skill, enemys, teammates);
|
effect.AlterSelectListBeforeSelection(caster, skill, enemys, teammates);
|
||||||
@ -3308,7 +3309,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange)
|
public List<Character> SelectTargets(Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange)
|
||||||
{
|
{
|
||||||
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AlterSelectListBeforeSelection(character, attack, enemys, teammates);
|
effect.AlterSelectListBeforeSelection(character, attack, enemys, teammates);
|
||||||
@ -3416,7 +3417,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
List<Character> characters = [actor, enemy];
|
List<Character> characters = [actor, enemy];
|
||||||
DamageType damageType = DamageType.Physical;
|
DamageType damageType = DamageType.Physical;
|
||||||
MagicType magicType = MagicType.None;
|
MagicType magicType = MagicType.None;
|
||||||
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
Dictionary<Effect, double> totalDamageBonus = [];
|
Dictionary<Effect, double> totalDamageBonus = [];
|
||||||
if (options.TriggerEffects)
|
if (options.TriggerEffects)
|
||||||
{
|
{
|
||||||
@ -3433,7 +3434,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. actor.Effects.Union(enemy.Effects).Distinct().Where(e => e.IsInEffect)];
|
effects = [.. actor.Effects.Union(enemy.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Physical, MagicType.None, totalDamageBonus);
|
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Physical, MagicType.None, totalDamageBonus);
|
||||||
@ -3449,7 +3450,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
bool checkCritical = true;
|
bool checkCritical = true;
|
||||||
if (isNormalAttack && options.CalculateEvade)
|
if (isNormalAttack && options.CalculateEvade)
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus))
|
if (!effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus))
|
||||||
@ -3464,7 +3465,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (dice < (enemy.EvadeRate + throwingBonus))
|
if (dice < (enemy.EvadeRate + throwingBonus))
|
||||||
{
|
{
|
||||||
bool isAlterEvaded = false;
|
bool isAlterEvaded = false;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.OnEvadedTriggered(actor, enemy, dice))
|
if (effect.OnEvadedTriggered(actor, enemy, dice))
|
||||||
@ -3500,7 +3501,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (options.CalculateCritical)
|
if (options.CalculateCritical)
|
||||||
{
|
{
|
||||||
// 暴击检定
|
// 暴击检定
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
||||||
@ -3517,7 +3518,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
options.CriticalDamage = finalDamage * (actor.CritDMG - 1);
|
options.CriticalDamage = finalDamage * (actor.CritDMG - 1);
|
||||||
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
|
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
|
||||||
WriteLine("暴击生效!!");
|
WriteLine("暴击生效!!");
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCriticalDamageTriggered(actor, enemy, dice);
|
effect.OnCriticalDamageTriggered(actor, enemy, dice);
|
||||||
@ -3549,7 +3550,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
|
if (options.ExpectedDamage == 0) options.ExpectedDamage = expectedDamage;
|
||||||
List<Character> characters = [actor, enemy];
|
List<Character> characters = [actor, enemy];
|
||||||
DamageType damageType = DamageType.Magical;
|
DamageType damageType = DamageType.Magical;
|
||||||
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
List<Effect> effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
Dictionary<Effect, double> totalDamageBonus = [];
|
Dictionary<Effect, double> totalDamageBonus = [];
|
||||||
if (options.TriggerEffects)
|
if (options.TriggerEffects)
|
||||||
{
|
{
|
||||||
@ -3566,7 +3567,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Magical, magicType, totalDamageBonus);
|
double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, DamageType.Magical, magicType, totalDamageBonus);
|
||||||
@ -3582,7 +3583,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
bool checkCritical = true;
|
bool checkCritical = true;
|
||||||
if (isNormalAttack && options.CalculateEvade)
|
if (isNormalAttack && options.CalculateEvade)
|
||||||
{
|
{
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus))
|
if (!effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus))
|
||||||
@ -3597,7 +3598,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (dice < (enemy.EvadeRate + throwingBonus))
|
if (dice < (enemy.EvadeRate + throwingBonus))
|
||||||
{
|
{
|
||||||
bool isAlterEvaded = false;
|
bool isAlterEvaded = false;
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (effect.OnEvadedTriggered(actor, enemy, dice))
|
if (effect.OnEvadedTriggered(actor, enemy, dice))
|
||||||
@ -3633,7 +3634,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (options.CalculateCritical)
|
if (options.CalculateCritical)
|
||||||
{
|
{
|
||||||
// 暴击检定
|
// 暴击检定
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
if (!effect.BeforeCriticalCheck(actor, enemy, isNormalAttack, ref throwingBonus))
|
||||||
@ -3650,7 +3651,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
options.CriticalDamage = finalDamage * (actor.CritDMG - 1);
|
options.CriticalDamage = finalDamage * (actor.CritDMG - 1);
|
||||||
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
|
finalDamage *= actor.CritDMG; // 暴击伤害倍率加成
|
||||||
WriteLine("暴击生效!!");
|
WriteLine("暴击生效!!");
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCriticalDamageTriggered(actor, enemy, dice);
|
effect.OnCriticalDamageTriggered(actor, enemy, dice);
|
||||||
@ -3959,7 +3960,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (skill != null)
|
if (skill != null)
|
||||||
{
|
{
|
||||||
bool interruption = true;
|
bool interruption = true;
|
||||||
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
if (!e.BeforeSkillCastWillBeInterrupted(caster, skill, interrupter))
|
if (!e.BeforeSkillCastWillBeInterrupted(caster, skill, interrupter))
|
||||||
@ -3971,7 +3972,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
_castingSkills.Remove(caster);
|
_castingSkills.Remove(caster);
|
||||||
WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!");
|
WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!");
|
||||||
effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect)];
|
effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
e.OnSkillCastInterrupted(caster, skill, interrupter);
|
e.OnSkillCastInterrupted(caster, skill, interrupter);
|
||||||
@ -3995,7 +3996,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
{
|
{
|
||||||
Skill skill = skillTarget.Skill;
|
Skill skill = skillTarget.Skill;
|
||||||
WriteLine($"[ {caster} ] 丢失了施法目标!!");
|
WriteLine($"[ {caster} ] 丢失了施法目标!!");
|
||||||
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect)];
|
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Distinct().Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnSkillCastInterrupted(caster, skill, interrupter);
|
effect.OnSkillCastInterrupted(caster, skill, interrupter);
|
||||||
@ -4040,6 +4041,10 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
/// <param name="skill"></param>
|
/// <param name="skill"></param>
|
||||||
public void SetCharacterPreCastSuperSkill(Character character, Skill skill)
|
public void SetCharacterPreCastSuperSkill(Character character, Skill skill)
|
||||||
{
|
{
|
||||||
|
if (LastRound.Actor == character && _isInRound)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_decisionPoints.TryGetValue(character, out DecisionPoints? dp) && dp != null)
|
if (_decisionPoints.TryGetValue(character, out DecisionPoints? dp) && dp != null)
|
||||||
{
|
{
|
||||||
if (dp.CurrentDecisionPoints < GameplayEquilibriumConstant.DecisionPointsCostSuperSkillOutOfTurn)
|
if (dp.CurrentDecisionPoints < GameplayEquilibriumConstant.DecisionPointsCostSuperSkillOutOfTurn)
|
||||||
@ -4104,7 +4109,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
|
|
||||||
AddCharacter(character, newHardnessTime, false);
|
AddCharacter(character, newHardnessTime, false);
|
||||||
skill.OnSkillCasting(this, character, [], []);
|
skill.OnSkillCasting(this, character, [], []);
|
||||||
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.AfterCharacterStartCasting(character, skill, []);
|
effect.AfterCharacterStartCasting(character, skill, []);
|
||||||
@ -4289,7 +4294,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
(target.ImmuneType & ImmuneType.Skilled) == ImmuneType.Skilled || (target.ImmuneType & ImmuneType.All) == ImmuneType.All;
|
(target.ImmuneType & ImmuneType.Skilled) == ImmuneType.Skilled || (target.ImmuneType & ImmuneType.All) == ImmuneType.All;
|
||||||
if (isImmune)
|
if (isImmune)
|
||||||
{
|
{
|
||||||
Effect[] effects = [.. skill.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. skill.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
// 自带无视免疫
|
// 自带无视免疫
|
||||||
@ -4301,7 +4306,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
if (!ignore)
|
if (!ignore)
|
||||||
{
|
{
|
||||||
Character[] characters = [character, target];
|
Character[] characters = [character, target];
|
||||||
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
// 特效免疫检定不通过可无视免疫
|
// 特效免疫检定不通过可无视免疫
|
||||||
@ -4345,7 +4350,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
bool checkExempted = true;
|
bool checkExempted = true;
|
||||||
double throwingBonus = 0;
|
double throwingBonus = 0;
|
||||||
Character[] characters = source != null ? [character, source] : [character];
|
Character[] characters = source != null ? [character, source] : [character];
|
||||||
Effect[] effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).Distinct()];
|
Effect[] effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.IsInEffect)).OrderByDescending(e => e.Priority).Distinct()];
|
||||||
foreach (Effect e in effects)
|
foreach (Effect e in effects)
|
||||||
{
|
{
|
||||||
if (!e.OnExemptionCheck(character, source, effect, isEvade, ref throwingBonus))
|
if (!e.OnExemptionCheck(character, source, effect, isEvade, ref throwingBonus))
|
||||||
@ -4520,7 +4525,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
_decisionPoints[character] = dp;
|
_decisionPoints[character] = dp;
|
||||||
}
|
}
|
||||||
InquiryResponse response = OnCharacterInquiryEvent(character, dp, options);
|
InquiryResponse response = OnCharacterInquiryEvent(character, dp, options);
|
||||||
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect)];
|
Effect[] effects = [.. character.Effects.Where(e => e.IsInEffect).OrderByDescending(e => e.Priority)];
|
||||||
foreach (Effect effect in effects)
|
foreach (Effect effect in effects)
|
||||||
{
|
{
|
||||||
effect.OnCharacterInquiry(character, options, response);
|
effect.OnCharacterInquiry(character, options, response);
|
||||||
|
|||||||
@ -12,6 +12,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public double MinNumberValue { get; set; } = 0;
|
public double MinNumberValue { get; set; } = 0;
|
||||||
public double MaxNumberValue { get; set; } = 0;
|
public double MaxNumberValue { get; set; } = 0;
|
||||||
public double DefaultNumberValue { get; set; } = 0;
|
public double DefaultNumberValue { get; set; } = 0;
|
||||||
|
public bool CanCancel { get; set; } = true;
|
||||||
public Dictionary<string, object> CustomArgs { get; set; } = [];
|
public Dictionary<string, object> CustomArgs { get; set; } = [];
|
||||||
|
|
||||||
public InquiryOptions(InquiryType type, string topic)
|
public InquiryOptions(InquiryType type, string topic)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ namespace Milimoe.FunGame.Core.Model
|
|||||||
public List<string> Choices { get; set; } = [];
|
public List<string> Choices { get; set; } = [];
|
||||||
public string TextResult { get; set; } = "";
|
public string TextResult { get; set; } = "";
|
||||||
public double NumberResult { get; set; } = 0;
|
public double NumberResult { get; set; } = 0;
|
||||||
|
public bool Cancel { get; set; } = false;
|
||||||
public Dictionary<string, object> CustomResponse { get; set; } = [];
|
public Dictionary<string, object> CustomResponse { get; set; } = [];
|
||||||
|
|
||||||
public InquiryResponse(InquiryType type, string topic)
|
public InquiryResponse(InquiryType type, string topic)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user