修改豁免持续时间的位置

This commit is contained in:
milimoe 2026-01-28 00:55:44 +08:00
parent 9448de07c3
commit 0f054839ca
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
4 changed files with 366 additions and 4 deletions

View File

@ -273,6 +273,7 @@
= 4133,
= 4134,
= 4135,
= 4136
= 4136,
= 4137
}
}

View File

@ -0,0 +1,102 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
{
public class : Effect
{
public override long Id => (long)PassiveEffectID.;
public override string Name { get; set; } = "持续伤害";
public override string Description => $"此角色正受到持续伤害,每{GameplayEquilibriumConstant.InGameTime}受到 {(_isPercentage ? $"{_durationDamagePercent * 100:0.##}% [ {Damage:0.##} ]" : Damage.ToString("0.##"))} 点{CharacterSet.GetDamageTypeName(_damageType)}。来自:[ {Source} ] 的 [ {Skill.Name} ]";
public override bool IsDebuff { get; set; } = true;
public override Character Source => _sourceCharacter;
public override bool Durative => _durative;
public override double Duration => _duration;
public override int DurationTurn => _durationTurn;
private readonly Character _targetCharacter;
private readonly Character _sourceCharacter;
private readonly bool _durative;
private readonly double _duration;
private readonly int _durationTurn;
private readonly bool _isPercentage;
private readonly double _durationDamage;
private readonly double _durationDamagePercent;
private readonly DamageType _damageType = DamageType.Physical;
private readonly DamageCalculationOptions? _options = null;
private double Damage => _isPercentage ? _targetCharacter.HP * _durationDamagePercent : _durationDamage;
public (Skill skill, Character targetCharacter, Character sourceCharacter, bool durative = false, double duration = 0, int durationTurn = 1,
bool isPercentage = true, double durationDamage = 100, double durationDamagePercent = 0.02, DamageType damageType = DamageType.Physical, DamageCalculationOptions? options = null) : base(skill)
{
GamingQueue = skill.GamingQueue;
_targetCharacter = targetCharacter;
_sourceCharacter = sourceCharacter;
_durative = durative;
_duration = duration;
_durationTurn = durationTurn;
_isPercentage = isPercentage;
_durationDamage = durationDamage;
_durationDamagePercent = durationDamagePercent;
_damageType = damageType;
_options = options;
}
private double GetDamage(double hp, double elapsed)
{
if (hp <= 0)
{
return 0;
}
double damage = _isPercentage ? hp * _durationDamagePercent : _durationDamage;
return damage * elapsed;
}
public override void OnTimeElapsed(Character character, double elapsed)
{
if (character == _targetCharacter && character.HP > 0)
{
double hp = character.HP;
double damage = GetDamage(hp, elapsed);
if (elapsed > 1)
{
damage = 0;
int loop = 0;
int elapsedSecond = (int)elapsed;
for (; loop < elapsedSecond; loop++)
{
double current = GetDamage(hp, 1);
damage += current;
hp -= current;
elapsed--;
}
if (elapsed > 0)
{
damage += GetDamage(hp, elapsed);
}
}
DamageToEnemy(Source, character, _damageType, MagicType, damage, _options);
}
}
public override void OnEffectGained(Character character)
{
if (_durative && RemainDuration == 0)
{
RemainDuration = Duration;
}
else if (RemainDurationTurn == 0)
{
RemainDurationTurn = DurationTurn;
}
AddEffectTypeToCharacter(character, [EffectType]);
}
public override void OnEffectLost(Character character)
{
RemoveEffectTypesFromCharacter(character);
}
}
}

View File

@ -0,0 +1,163 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
using Oshima.FunGame.OshimaModules.Effects.PassiveEffects;
using Oshima.FunGame.OshimaModules.Skills;
namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
{
public class : Effect
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description
{
get
{
SetDescription();
return $"{概率文本}对{Skill.TargetDescription()}施加{GetEffectTypeName(_effectType)} {持续时间}。{(_description != "" ? _description : "")}";
}
}
public override EffectType EffectType => _effectType;
public override DispelledType DispelledType => _dispelledType;
public override bool ExemptDuration => true;
private string => ActualProbability == 1 ? "" : $"{ActualProbability * 100:0.##}% 概率";
private double ActualProbability => Calculation.PercentageCheck(Level > 0 ? (_probability + _probabilityLevelGrowth * (Level - 1) * MagicEfficacy) : _probability);
private string => _durative && _duration > 0 ? $"{实际持续时间:0.##}" + $" {GameplayEquilibriumConstant.InGameTime}" : (!_durative && _durationTurn > 0 ? + " 回合" : $"0 {GameplayEquilibriumConstant.InGameTime}");
private double => _durative && _duration > 0 ? (_duration + _levelGrowth * (Level - 1) * MagicEfficacy) : (!_durative && _durationTurn > 0 ? ((int)Math.Round(_durationTurn + _levelGrowth * (Level - 1) * MagicEfficacy, 0, MidpointRounding.ToPositiveInfinity)) : 0);
private readonly EffectType _effectType;
private readonly bool _durative;
private readonly double _duration;
private readonly int _durationTurn;
private readonly double _levelGrowth;
private readonly double _probability;
private readonly double _probabilityLevelGrowth;
private readonly object[] _args;
private DispelledType _dispelledType = DispelledType.Weak;
private string _description = "";
public (Skill skill, EffectType effectType, bool durative = false, double duration = 0, int durationTurn = 1, double levelGrowth = 0, double probability = 0, double probabilityLevelGrowth = 0, params object[] args) : base(skill)
{
GamingQueue = skill.GamingQueue;
_effectType = effectType;
_durative = durative;
_duration = duration;
_durationTurn = durationTurn;
_levelGrowth = levelGrowth;
_probability = probability;
_probabilityLevelGrowth = probabilityLevelGrowth;
_args = args;
SetDescription();
}
public override void OnSkillCasted(Character caster, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
{
foreach (Character target in targets)
{
if (target.HP <= 0 || Random.Shared.NextDouble() > ActualProbability) continue;
Effect? e = null;
double duration = _duration + _levelGrowth * (Level - 1);
int durationTurn = Convert.ToInt32(_durationTurn + _levelGrowth * (Level - 1));
string tip = "";
switch (_effectType)
{
case EffectType.HealOverTime:
bool isPercentage = false;
double durationHeal = 0;
double durationHealPercent = 0;
double durationHealLevelGrowth = 0;
if (_args.Length > 0 && _args[0] is bool _)
{
isPercentage = (bool)_args[0];
}
if (_args.Length > 1 && _args[1] is double _)
{
durationHeal = (double)_args[1];
}
if (_args.Length > 2 && _args[2] is double _)
{
durationHealPercent = (double)_args[2];
}
if (_args.Length > 3 && _args[3] is double _)
{
durationHealLevelGrowth = (double)_args[3];
}
if (isPercentage && durationHealPercent > 0 || !isPercentage && durationHeal > 0)
{
if (Level > 0)
{
durationHeal += durationHealLevelGrowth * (Level - 1);
durationHealPercent += durationHealLevelGrowth * (Level - 1);
}
string healString = $"每{GameplayEquilibriumConstant.InGameTime}回复 {(isPercentage ? $"{durationHealPercent * 100:0.##}% " : durationHeal.ToString("0.##"))} 点生命值";
tip = $"[ {caster} ] 对 [ {target} ] 施加了{GetEffectTypeName(_effectType)} [ {target} ] 每{GameplayEquilibriumConstant.InGameTime}{healString}!持续时间:{持续时间}";
e = new (Skill, target, caster, _durative, duration, durationTurn, isPercentage, durationHeal, durationHealPercent)
{
EffectType = _effectType
};
}
break;
default:
break;
}
if (e != null && !CheckExemption(caster, target, e))
{
WriteLine(tip);
target.Effects.Add(e);
e.OnEffectGained(target);
GamingQueue?.LastRound.AddApplyEffects(target, e.EffectType);
}
}
}
private void SetDescription()
{
switch (_effectType)
{
case EffectType.HealOverTime:
_dispelledType = DispelledType.Weak;
bool isPercentage = false;
double durationHeal = 0;
double durationHealPercent = 0;
double durationHealLevelGrowth = 0;
if (_args.Length > 0 && _args[0] is bool _)
{
isPercentage = (bool)_args[0];
}
if (_args.Length > 1 && _args[1] is double _)
{
durationHeal = (double)_args[1];
}
if (_args.Length > 2 && _args[2] is double _)
{
durationHealPercent = (double)_args[2];
}
if (_args.Length > 3 && _args[3] is double _)
{
durationHealLevelGrowth = (double)_args[3];
}
if (isPercentage && durationHealPercent > 0 || !isPercentage && durationHeal > 0)
{
if (Level > 0) durationHeal += durationHealLevelGrowth * (Level - 1);
if (Level > 0) durationHealPercent += durationHealLevelGrowth * (Level - 1);
string healString = $"每{GameplayEquilibriumConstant.InGameTime}回复 {(isPercentage ? $"{durationHealPercent * 100:0.##}% " : durationHeal.ToString("0.##"))} 点生命值";
_description = $"{GetEffectTypeName(_effectType)}:每{GameplayEquilibriumConstant.InGameTime}{healString}!持续时间:{持续时间}";
}
break;
default:
break;
}
}
private static string GetEffectTypeName(EffectType type)
{
return type switch
{
_ => SkillSet.GetEffectTypeName(type)
};
}
}
}

View File

@ -1,6 +1,8 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
using Oshima.FunGame.OshimaModules.Effects.PassiveEffects;
using Oshima.FunGame.OshimaModules.Skills;
@ -15,14 +17,15 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
get
{
SetDescription();
return $"{ActualProbability * 100:0.##}% 概率对{Skill.TargetDescription()}造成{GetEffectTypeName(_effectType)} {持续时间}。{(_description != "" ? _description : "")}";
return $"{概率文本}对{Skill.TargetDescription()}造成{GetEffectTypeName(_effectType)} {持续时间}。{(_description != "" ? _description : "")}";
}
}
public override EffectType EffectType => _effectType;
public override DispelledType DispelledType => _dispelledType;
public override bool ExemptDuration => true;
private double ActualProbability => Level > 0 ? (_probability + _probabilityLevelGrowth * (Level - 1) * MagicEfficacy) : _probability;
private string => ActualProbability == 1 ? "" : $"{ActualProbability * 100:0.##}% 概率";
private double ActualProbability => Calculation.PercentageCheck(Level > 0 ? (_probability + _probabilityLevelGrowth * (Level - 1) * MagicEfficacy) : _probability);
private string => _durative && _duration > 0 ? $"{实际持续时间:0.##}" + $" {GameplayEquilibriumConstant.InGameTime}" : (!_durative && _durationTurn > 0 ? + " 回合" : $"0 {GameplayEquilibriumConstant.InGameTime}");
private double => _durative && _duration > 0 ? (_duration + _levelGrowth * (Level - 1) * MagicEfficacy) : (!_durative && _durationTurn > 0 ? ((int)Math.Round(_durationTurn + _levelGrowth * (Level - 1) * MagicEfficacy, 0, MidpointRounding.ToPositiveInfinity)) : 0);
private readonly EffectType _effectType;
@ -149,11 +152,63 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
tip = $"[ {caster} ] 对 [ {target} ] 造成了缴械!持续时间:{持续时间}";
e = new (Skill, caster, _durative, duration, durationTurn);
break;
case EffectType.Burn:
case EffectType.Poison:
isPercentage = false;
durationDamage = 0;
durationDamagePercent = 0;
durationDamageLevelGrowth = 0;
damageType = DamageType.Magical;
DamageCalculationOptions? options = null;
if (_args.Length > 0 && _args[0] is bool _)
{
isPercentage = (bool)_args[0];
}
if (_args.Length > 1 && _args[1] is double _)
{
durationDamage = (double)_args[1];
}
if (_args.Length > 2 && _args[2] is double _)
{
durationDamagePercent = (double)_args[2];
}
if (_args.Length > 3 && _args[3] is double _)
{
durationDamageLevelGrowth = (double)_args[3];
}
if (_args.Length > 0 && _args[4] is DamageType _)
{
damageType = (DamageType)_args[4];
}
if (_args.Length > 0 && _args[5] is DamageCalculationOptions _)
{
options = (DamageCalculationOptions)_args[5];
}
if (isPercentage && durationDamagePercent > 0 || !isPercentage && durationDamage > 0)
{
if (Level > 0) durationDamage += durationDamageLevelGrowth * (Level - 1);
if (Level > 0) durationDamagePercent += durationDamageLevelGrowth * (Level - 1);
string damageString = isPercentage ? $"受到 {durationDamagePercent * 100:0.##}% 当前生命值的" : $"受到 {durationDamage:0.##} 点" + CharacterSet.GetDamageTypeName(damageType);
tip = $"[ {caster} ] 对 [ {target} ] 造成了{GetEffectTypeName(_effectType)} [ {target} ] 每{GameplayEquilibriumConstant.InGameTime}{damageString}!持续时间:{持续时间}";
e = new (Skill, target, caster, _durative, duration, durationTurn, isPercentage, durationDamage, durationDamagePercent, damageType, options)
{
EffectType = _effectType
};
}
break;
case EffectType.InterruptCasting:
e = new (Skill);
break;
default:
break;
}
if (e != null && !CheckExemption(caster, target, e))
{
if (e is ddsf)
{
ddsf.OnSkillCasted(caster, [target], [], []);
continue;
}
WriteLine(tip);
target.Effects.Add(e);
e.OnEffectGained(target);
@ -258,6 +313,45 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
_dispelledType = DispelledType.Weak;
_description = "缴械:无法普通攻击。";
break;
case EffectType.Burn:
case EffectType.Poison:
_dispelledType = DispelledType.Weak;
isPercentage = false;
durationDamage = 0;
durationDamagePercent = 0;
durationDamageLevelGrowth = 0;
damageType = DamageType.Magical;
if (_args.Length > 0 && _args[0] is bool _)
{
isPercentage = (bool)_args[0];
}
if (_args.Length > 1 && _args[1] is double _)
{
durationDamage = (double)_args[1];
}
if (_args.Length > 2 && _args[2] is double _)
{
durationDamagePercent = (double)_args[2];
}
if (_args.Length > 3 && _args[3] is double _)
{
durationDamageLevelGrowth = (double)_args[3];
}
if (_args.Length > 0 && _args[4] is DamageType _)
{
damageType = (DamageType)_args[4];
}
if (isPercentage && durationDamagePercent > 0 || !isPercentage && durationDamage > 0)
{
if (Level > 0) durationDamage += durationDamageLevelGrowth * (Level - 1);
if (Level > 0) durationDamagePercent += durationDamageLevelGrowth * (Level - 1);
string damageString = isPercentage ? $"受到 {durationDamagePercent * 100:0.##}% 当前生命值的" : $"受到 {durationDamage:0.##} 点" + CharacterSet.GetDamageTypeName(damageType);
_description = $"{GetEffectTypeName(_effectType)}:每{GameplayEquilibriumConstant.InGameTime}{damageString}!持续时间:{持续时间}";
}
break;
case EffectType.InterruptCasting:
_description = "打断施法:中断其正在进行的吟唱。";
break;
default:
break;
}
@ -271,6 +365,8 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
EffectType.Silence => "封技",
EffectType.Bleed => "气绝",
EffectType.Cripple => "战斗不能",
EffectType.Burn => "燃烧",
EffectType.Poison => "中毒",
_ => SkillSet.GetEffectTypeName(type)
};
}