添加新技能和测试

This commit is contained in:
milimoe 2026-01-15 01:27:48 +08:00
parent ea0120e768
commit 27616e0665
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
21 changed files with 698 additions and 75 deletions

View File

@ -272,6 +272,7 @@
= 4132,
= 4133,
= 4134,
= 4135
= 4135,
= 4136
}
}

View File

@ -0,0 +1,50 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
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 => "复制技能";
public override string Description => $"此角色持有技能 [ {_skill.Name} ] 的复制品。来自:[ {Source} ]";
public override EffectType EffectType => EffectType.Mark;
public override Character Source => _sourceCharacter;
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
public Skill CopiedSkill => _skill;
private readonly Character _sourceCharacter;
private readonly Skill _skill;
public (Skill skill, Character sourceCharacter, Skill copiedSkill) : base(skill)
{
GamingQueue = skill.GamingQueue;
_sourceCharacter = sourceCharacter;
_skill = copiedSkill.Copy();
_skill.Level = copiedSkill.Level;
}
public CharacterActionType LastType { get; set; } = CharacterActionType.None;
public Skill? LastSkill { get; set; } = null;
public override void OnEffectGained(Character character)
{
_skill.Character = character;
_skill.OnLevelUp();
character.Skills.Add(_skill);
}
public override void OnEffectLost(Character character)
{
foreach (Effect effect in _skill.Effects)
{
if (character.Effects.Remove(effect))
{
effect.OnEffectLost(character);
}
}
character.Skills.Remove(_skill);
}
}
}

View File

@ -1,6 +1,8 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
using Oshima.FunGame.OshimaModules.Skills;
namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
{
@ -8,18 +10,104 @@ namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
{
public override long Id => (long)PassiveEffectID.;
public override string Name => "宫监手标记";
public override string Description => $"此角色持有宫监手标记。来自:[ {Source} ]";
public override string Description => $"{放监.任务要求}。来自:[ {Source} ]";
public override EffectType EffectType => EffectType.Mark;
public override bool IsDebuff => true;
public override Character Source => _sourceCharacter;
public override DispelledType DispelledType { get; set; } = DispelledType.Weak;
public override DispelledType DispelledType { get; set; } = DispelledType.CannotBeDispelled;
private readonly Character _sourceCharacter;
private readonly Character _targetCharacter;
private readonly ;
private bool = false;
private bool = false;
public (Skill skill, Character sourceCharacter) : base(skill)
public (Skill skill, Character sourceCharacter, Character targetCharacter, effect) : base(skill)
{
GamingQueue = skill.GamingQueue;
_sourceCharacter = sourceCharacter;
_targetCharacter = targetCharacter;
= effect;
}
public void (Character character)
{
WriteLine($"[ {character} ] 的「放监」任务 [ 对友方角色普通攻击 ] 完成!");
= true;
CheckComplete(character);
}
public void (Character character)
{
WriteLine($"[ {character} ] 的「放监」任务 [ 对{Source}释放指向性技能 ] 完成!");
= true;
CheckComplete(character);
}
public void CheckComplete(Character character)
{
if ( && )
{
character.Effects.Remove(this);
WriteLine($"[ {character} ] 已消除宫监手标记!");
}
}
public override void AlterSelectListBeforeSelection(Character character, ISkill skill, List<Character> enemys, List<Character> teammates)
{
if (skill is NormalAttack)
{
enemys.AddRange(teammates);
}
}
public override bool BeforeCriticalCheck(Character actor, Character enemy, bool isNormalAttack, ref double throwingBonus)
{
if (actor == _targetCharacter && isNormalAttack)
{
throwingBonus += 300;
}
return true;
}
public override bool BeforeEvadeCheck(Character actor, Character enemy, ref double throwingBonus)
{
if (actor == _targetCharacter)
{
return false;
}
return true;
}
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{
if (character == _targetCharacter && isNormalAttack && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical))
{
if (GamingQueue != null && GamingQueue.IsTeammate(character, enemy))
{
(character);
}
}
}
public override void AfterDeathCalculation(Character death, Character? killer, Dictionary<Character, int> continuousKilling, Dictionary<Character, int> earnedMoney, Character[] assists)
{
if (death == _targetCharacter)
{
death.Effects.Remove(this);
}
if (death == _sourceCharacter)
{
_targetCharacter.Effects.Remove(this);
}
}
public override void OnEffectLost(Character character)
{
if (! || !)
{
.(character, ! && ! ? 2 : 1);
}
}
}
}

View File

@ -21,5 +21,37 @@ namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
GamingQueue = skill.GamingQueue;
_sourceCharacter = sourceCharacter;
}
public override void OnTurnStart(Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{
if (GamingQueue is null)
{
return;
}
List<Character> enemies = GamingQueue.GetEnemies(character);
if (enemies.Contains(Source) && Random.Shared.NextDouble() < 0.65)
{
WriteLine($"[ {character} ] 受到了{nameof(时雨标记)}的影响,陷入了混乱!!!");
Effect e = new (Skill, character, false, 0, 1);
character.Effects.Add(e);
e.OnEffectGained(character);
}
}
public override double AlterActualDamageAfterCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult, ref bool isEvaded, Dictionary<Effect, double> totalDamageBonus)
{
if (GamingQueue is null)
{
return 0;
}
List<Character> teammates = GamingQueue.GetTeammates(character);
if ((character == Source || teammates.Contains(Source)) && enemy.Effects.Any(e => e is ))
{
double bonus = damage;
WriteLine($"[ {character} ] 受到了{nameof(时雨标记)}的影响,伤害提高了 {bonus:0.##} 点!");
return bonus;
}
return 0;
}
}
}

View File

@ -1,5 +1,7 @@
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.OpenEffects;
namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
@ -16,11 +18,80 @@ namespace Oshima.FunGame.OshimaModules.Effects.PassiveEffects
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
private readonly Character _sourceCharacter;
private readonly Character _targetCharacter;
public (Skill skill, Character sourceCharacter) : base(skill)
public (Skill skill, Character sourceCharacter, Character targetCharacter) : base(skill)
{
GamingQueue = skill.GamingQueue;
_sourceCharacter = sourceCharacter;
_targetCharacter = targetCharacter;
}
public CharacterActionType LastType { get; set; } = CharacterActionType.None;
public Skill? LastSkill { get; set; } = null;
public override void OnCharacterActionStart(Character actor, DecisionPoints dp, CharacterActionType type)
{
if (type == CharacterActionType.NormalAttack)
{
LastType = type;
}
}
public override bool BeforeSkillCasted(Character caster, Skill skill, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
{
LastType = CharacterActionType.CastSkill;
LastSkill = skill;
return true;
}
public override void AfterDeathCalculation(Character death, Character? killer, Dictionary<Character, int> continuousKilling, Dictionary<Character, int> earnedMoney, Character[] assists)
{
if (GamingQueue != null && killer != null && killer == _targetCharacter && Source != null && death != Source && GamingQueue.Queue.Contains(Source))
{
WriteLine($"[ {Source} ] 正在观察 [ {killer} ] 的情绪。");
if (LastType == CharacterActionType.NormalAttack)
{
Source.NormalAttack.SetMagicType(new(Skill.Effects.First(), true, MagicType, 999), GamingQueue);
Effect e = new IgnoreEvade(Skill, new()
{
{ "p", 1 }
}, Source)
{
Durative = false,
DurationTurn = 3,
RemainDurationTurn = 3
};
e.OnEffectGained(Source);
Source.Effects.Add(e);
WriteLine($"[ {Source} ] 获得了无视闪避效果,持续 3 回合!");
}
else if (LastType == CharacterActionType.CastSkill && LastSkill != null)
{
e = new(Skill, Source, LastSkill)
{
Durative = false,
DurationTurn = 3,
RemainDurationTurn = 3
};
e.CopiedSkill.Values[nameof()] = 1;
e.CopiedSkill.CurrentCD = 0;
e.CopiedSkill.Enable = true;
e.CopiedSkill.IsInEffect = false;
e.OnEffectGained(Source);
Source.Effects.Add(e);
WriteLine($"[ {Source} ] 复制了 [ {killer} ] 的技能:{LastSkill.Name}");
}
Effect e2 = new (Skill, Source)
{
Durative = false,
DurationTurn = 3,
RemainDurationTurn = 3
};
e2.OnEffectGained(killer);
killer.Effects.Add(e2);
WriteLine($"[ {Source} ] 给予了 [ {killer} ] 时雨标记!");
}
}
}
}

View File

@ -35,6 +35,7 @@ namespace Oshima.FunGame.OshimaModules.Items
public override string Description => string.Join("", Effects.Select(e => e.Description));
private readonly double = 180;
private readonly double = 4;
private readonly double = 0.2;
public (Character? character = null, Item? item = null) : base(SkillType.Passive, character)
@ -44,9 +45,11 @@ namespace Oshima.FunGame.OshimaModules.Items
Dictionary<string, object> values = new()
{
{ "exspd", },
{ "exmov", },
{ "exacc", }
};
Effects.Add(new ExSPD(this, values, character));
Effects.Add(new ExMOV(this, values, character));
Effects.Add(new AccelerationCoefficient(this, values, character));
}

View File

@ -11,7 +11,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override string Description => Effects.Count > 0 ? (()Effects.First()).GeneralDescription : "";
public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : "";
public override double EPCost => 100;
public override double CD => 80;
public override double CD => 100;
public override double HardnessTime { get; set; } = 5;
public override bool CanSelectSelf => true;
public override bool CanSelectEnemy => false;
@ -29,6 +29,8 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override string Description { get; set; } = "";
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
public string GeneralDescription => $"将雇佣兵数量立即补全至 {雇佣兵团特效.最大数量} 名,每名雇佣兵的生命值回复至满并提升 {攻击力提升 * 100:0.##}% 攻击力。在 {持续时间} {GameplayEquilibriumConstant.InGameTime}内,场上的每名雇佣兵额外为{Skill.SkillOwner()}提供 {攻击力 * 100:0.##}% 攻击力和 {行动速度:0.##} 点行动速度、{加速系数 * 100:0.##}% 加速系数、{冷却缩减 * 100:0.##}% 冷却缩减。";
public override bool Durative => true;
public override double Duration => ;
public double => 20 + 2 * (Skill.Level - 1);
public const double = 0.04;
@ -86,7 +88,6 @@ namespace Oshima.FunGame.OshimaModules.Skills
}
}
(caster);
GamingQueue?.LastRound.AddApplyEffects(caster, EffectType.CritBoost, EffectType.PenetrationBoost);
}
public void (Character character)

View File

@ -34,13 +34,14 @@ namespace Oshima.FunGame.OshimaModules.Skills
public const int = 2;
public const int = 5;
public const int = 20;
public const double = 0.25;
public const double = 0.15;
public const double = 0.4;
public override void AfterDeathCalculation(Character death, Character? killer, Dictionary<Character, int> continuousKilling, Dictionary<Character, int> earnedMoney, Character[] assists)
{
if (death is gyb)
{
WriteLine($"[ {killer} ] 杀死了 [ {death} ]");
.Remove(gyb);
if (.Count < && Skill.CurrentCD == 0)
{

View File

@ -33,10 +33,14 @@ namespace Oshima.FunGame.OshimaModules.Skills
public double { get; set; } = 0.12;
private bool = false;
public override bool BeforeCriticalCheck(Character actor, Character enemy, ref double throwingBonus)
public override bool BeforeCriticalCheck(Character actor, Character enemy, bool isNormalAttack, ref double throwingBonus)
{
if (actor == Skill.Character)
{
return !;
}
return true;
}
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{

View File

@ -32,7 +32,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"标记{Skill.TargetDescription()},持续 {持续时间:0.##} {GameplayEquilibriumConstant.InGameTime}。立即对标记目标造成 {直接伤害:0.##} 点{CharacterSet.GetDamageTypeName(DamageType.Magical, MagicType)}。" +
$"在持续时间内{爆炸伤害描述}在此期间,{Skill.SkillOwner()}的力量提升 60% [ {力量提升:0.##} ],并且 [ {nameof(深海之戟)} ] 改变为相同机制。无视免疫。";
$"在持续时间内{爆炸伤害描述}在此期间,{Skill.SkillOwner()}的力量提升 60% [ {力量提升:0.##} ],并且 [ {nameof(深海之戟)} ] 改变为相同机制,可以叠加触发。无视免疫。";
public override bool Durative => true;
public override double Duration => ;
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
@ -42,7 +42,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
public string => $"对受到标记的目标造成伤害时将产生爆炸,爆炸将产生 {分裂伤害系数 * 100:0.##}% 分裂伤害。分裂伤害为全图索敌,会优先分裂至三个在持续时间内对{Skill.SkillOwner()}造成伤害最多的敌人,若没有符合条件的敌人或敌人数量不足,则将分裂至被标记的敌人,或至多三个随机的敌人。";
public double => 180 + 240 * (Skill.Level - 1);
public double => 25 + 2 * (Skill.Level - 1);
public double => 0.4 + 0.08 * (Skill.Level - 1);
public double => 0.25 + 0.05 * (Skill.Level - 1);
public double => 0.6 * (Skill.Character?.BaseSTR ?? 0);
public Dictionary<Character, double> { get; set; } = [];

View File

@ -35,7 +35,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
string str = $"分裂伤害:{分裂百分比 * 100:0.##}%。无视免疫。";
if ( != null)
{
return $"技能机制受 [ {nameof(海王星的野望)} ] 影响而改变:{野望.爆炸伤害描述}{str}";
return $"技能机制受 [ {nameof(海王星的野望)} ] 影响而改变:{野望.爆炸伤害描述}未攻击标记目标时,按原机制,在普通攻击暴击时分裂。";
}
else if (GamingQueue?.Map != null)
{
@ -49,12 +49,12 @@ namespace Oshima.FunGame.OshimaModules.Skills
}
public override ImmuneType IgnoreImmune => ImmuneType.All;
public double => Math.Min(0.75, 0.3 + (Skill.Character?.Level ?? 0 + 0.00) / 100);
public double => Math.Min(0.5, 0.3 + (Skill.Character?.Level ?? 0 + 0.00) / 200);
public ? { get; set; } = null;
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{
if ( != null && enemy.Effects.FirstOrDefault(e => e is ) is e)
if (character == Skill.Character && != null && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && enemy.Effects.FirstOrDefault(e => e is ) is e)
{
.(character, enemy, actualDamage, damageType, magicType);
}

View File

@ -67,7 +67,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
}
}
public override bool BeforeCriticalCheck(Character actor, Character enemy, ref double throwingBonus)
public override bool BeforeCriticalCheck(Character actor, Character enemy, bool isNormalAttack, ref double throwingBonus)
{
if (actor == Skill.Character)
{

View File

@ -42,13 +42,13 @@ namespace Oshima.FunGame.OshimaModules.Skills
private double HP = 0;
private double = 0;
private readonly double = 0.35;
private readonly double = 0.1;
private readonly double = 0.15;
private readonly int 40 = 40;
private readonly int 40 = 20;
private readonly int 40 = 80;
private readonly int 40 = 50;
private readonly int 40 = 90;
private readonly int 40 = 60;
private readonly int 40 = 120;
private readonly int 40 = 90;
private readonly int 40 = 100;
private double (double damage)
{
@ -110,6 +110,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
if (character == Skill.Character && )
{
= false;
= 0;
double ls = actualDamage * ;
HealToTarget(character, character, ls, triggerEffects: false);
@ -121,7 +122,6 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
if ( && actor == Skill.Character)
{
= false;
throwingBonus -= 0.3;
}
return true;

View File

@ -1,5 +1,6 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
using Oshima.FunGame.OshimaModules.Effects.PassiveEffects;
namespace Oshima.FunGame.OshimaModules.Skills
@ -25,18 +26,76 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"{Skill.SkillOwner()}进入 [ {nameof(长期监视)} ] 状态,时刻监视着场上的一举一动。当场上有角色死亡时,如果该角色死于技能,则{Skill.SkillOwner()}复制该技能获得使用权,持续 3 回合,该复制品没有冷却时间;如果该角色死于普通攻击,则{Skill.SkillOwner()}的普通攻击将转为魔法伤害并且无视闪避,持续 3 回合。" +
$"接着,{Skill.SkillOwner()}给予击杀者 [ {nameof(时雨标记)} ]。{Skill.SkillOwner()}在造成魔法伤害时,会基于伤害值的 50% 治疗持有标记的友方角色;{Skill.SkillOwner()}与所有持有标记的友方角色对持有标记的敌方角色的伤害加成提升 100%,并且使持有标记的敌方角色在持续时间内的回合开始阶段,有 60% 概率陷入混乱。" +
public override string Description => $"{Skill.SkillOwner()}在其首个可行动回合的开始阶段进入 [ {nameof(长期监视)} ] 状态,时刻监视着场上的一举一动。当场上有角色死亡时,如果该角色死于技能,则{Skill.SkillOwner()}复制该技能获得使用权,持续 3 回合,该复制品没有冷却时间;如果该角色死于普通攻击,则{Skill.SkillOwner()}的普通攻击将转为魔法伤害并且无视闪避,持续 3 回合。" +
$"接着,{Skill.SkillOwner()}给予击杀者 [ {nameof(时雨标记)} ]。{Skill.SkillOwner()}在造成魔法伤害时,会基于伤害值的 50% 治疗持有标记的友方角色;{Skill.SkillOwner()}与所有持有标记的友方角色对持有标记的敌方角色的伤害加成提升 100%,并且使持有标记的敌方角色在持续时间内的回合开始阶段,有 65% 概率陷入混乱。" +
$"混乱:进入行动受限状态,失控并随机行动,且在进行攻击指令时,可能会选取友方角色为目标。时雨标记持续 3 回合。";
public override void OnEffectGained(Character character)
{
private bool = false;
public override void OnTurnStart(Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{
if (!)
{
= true;
();
}
}
public override void OnEffectLost(Character character)
public override void OnTimeElapsed(Character character, double elapsed)
{
if ()
{
();
}
}
public override void OnCharacterActionTaken(Character actor, DecisionPoints dp, CharacterActionType type)
{
Skill[] skills = [.. actor.Skills.Where(s => s.Values.TryGetValue(nameof(), out object? value) && value.Equals(1))];
foreach (Skill skill in skills)
{
skill.CurrentCD = 0;
skill.Enable = true;
}
}
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{
if (character != Skill.Character || GamingQueue is null || damageType != DamageType.Magical || (damageResult != DamageResult.Normal && damageResult != DamageResult.Critical))
{
return;
}
Character[] characters = [.. GamingQueue.GetTeammates(character).Where(c => c.Effects.Any(e => e is ))];
if (characters.Length > 0)
{
WriteLine($"[ {character} ] 发动了开宫!");
double heal = actualDamage * 0.5;
foreach (Character target in characters)
{
HealToTarget(character, target, heal);
}
}
}
public void ()
{
if (GamingQueue is null || Skill.Character is null)
{
return;
}
foreach (Character character in GamingQueue.Queue)
{
if (character == Skill.Character)
{
continue;
}
if (!character.Effects.Any(e => e is ))
{
Effect e = new (Skill, Skill.Character, character);
character.Effects.Add(e);
e.OnEffectGained(character);
}
}
}
}
}

View File

@ -1,6 +1,8 @@
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;
namespace Oshima.FunGame.OshimaModules.Skills
{
@ -15,39 +17,116 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override double HardnessTime { get; set; } = 14;
public override bool CanSelectSelf => true;
public override bool CanSelectEnemy => false;
public Passive { get; set; }
public (Character? character = null) : base(SkillType.SuperSkill, character)
{
Effects.Add(new (this));
Passive = new (this);
}
public override IEnumerable<Effect> AddPassiveEffectToCharacter()
{
return [Passive];
}
}
public class : Effect
public class (Skill skill) : Effect(skill)
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description { get; set; } = "";
public override string Description => $"{Skill.SkillOwner()}阻止任何来自持有 [ 宫监手标记 ] 的角色所发起的指向性技能攻击。";
public override bool DurativeWithoutDuration => true;
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
public string => $"使场上现有的时雨标记变得不可驱散,并且刷新为持续 3 回合。并给予持有时雨标记的敌方角色 [ 宫监手标记 ],宫监手标记不可驱散,持续 3 回合。持有宫监手标记的角色,必须完成以下两个任务以消除标记,否则将在标记消失时受到基于{Skill.SkillOwner()} {核心属性系数 * 100:0.##}% 核心属性 + {攻击力系数 * 100:0.##}% 攻击力 [ {Skill.Character?.PrimaryAttributeValue * 核心属性系数 + Skill.Character?.ATK * 攻击力系数:0.##} ] 的真实伤害:\r\n" +
$"1. 使用 [ 普通攻击 ] 攻击一次队友,此伤害必定暴击且无视闪避;\r\n2. 对{Skill.SkillOwner()}释放一个指向性技能,{Skill.SkillOwner()}将此技能效果无效化并且复制该技能获得使用权持续 4 回合,该复制品没有冷却时间。";
public double => 1.1 * Skill.Level;
public double => 0.4 + 0.2 * (Skill.Level - 1);
public (Skill skill) : base(skill)
public override bool BeforeSkillCasted(Character caster, Skill skill, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
{
Description = ;
if (Skill.Character != null && caster.Effects.FirstOrDefault(e => e is ) is effect)
{
WriteLine($"[ {Skill.Character} ] 高声呼喊:“宫监手,放监!”");
e = new(Skill, Skill.Character, skill)
{
Durative = false,
DurationTurn = 4,
RemainDurationTurn = 4
};
e.CopiedSkill.Values[nameof()] = 1;
e.CopiedSkill.CurrentCD = 0;
e.CopiedSkill.Enable = true;
e.CopiedSkill.IsInEffect = false;
e.OnEffectGained(Skill.Character);
Skill.Character.Effects.Add(e);
WriteLine($"[ {Skill.Character} ] 复制了 [ {caster} ] 的技能:{skill.Name}");
effect.(caster);
// 返回 false 让框架处理阻止技能对该角色的释放
return false;
}
return true;
}
public override void OnCharacterActionTaken(Character actor, DecisionPoints dp, CharacterActionType type)
{
Skill[] skills = [.. actor.Skills.Where(s => s.Values.TryGetValue(nameof(), out object? value) && value.Equals(1))];
foreach (Skill skill in skills)
{
skill.CurrentCD = 0;
skill.Enable = true;
}
}
}
public class (Skill skill) : Effect(skill)
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => ;
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
public string => $"使场上现有的时雨标记变得不可驱散,并且刷新为持续 3 回合。并给予持有时雨标记的敌方角色 [ 宫监手标记 ],宫监手标记不可驱散,持续 3 回合。{任务要求}";
public string => $"持有宫监手标记的角色,必须完成以下两个任务以消除标记,否则将在标记消失时,每个未完成的任务给予角色基于{Skill.SkillOwner()} {核心属性系数 * 100:0.##}% 核心属性 + {攻击力系数 * 100:0.##}% 攻击力 [ {Skill.Character?.PrimaryAttributeValue * 核心属性系数 + Skill.Character?.ATK * 攻击力系数:0.##} ] 的真实伤害:\r\n" +
$"1. 使用 [ 普通攻击 ] 攻击一次队友,此伤害必定暴击且无视闪避;\r\n2. 对{Skill.SkillOwner()}释放一个指向性技能,{Skill.SkillOwner()}将此技能效果无效化并且复制该技能获得使用权持续 4 回合,该复制品没有冷却时间。\r\n注意在宫监手标记被消除前对{Skill.SkillOwner()}释放指向性技能始终会触发无效化和复制效果。杀死{Skill.SkillOwner()}可以终止所有放监任务。";
public double => 0.8 * Skill.Level;
public double => 0.2 + 0.15 * (Skill.Level - 1);
public void (Character character, int count)
{
if (Skill.Character != null)
{
WriteLine($"[ {character} ] 未完成「放监」任务!");
for (int i = 0; i < count; i++)
{
double damage = Skill.Character.PrimaryAttributeValue * + Skill.Character.ATK * ;
DamageToEnemy(Skill.Character, character, DamageType.True, MagicType, damage);
}
}
}
public override void OnSkillCasted(Character caster, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
{
RemainDuration = Duration;
if (!caster.Effects.Contains(this))
if (GamingQueue != null)
{
caster.Effects.Add(this);
OnEffectGained(caster);
List<Character> enemies = GamingQueue.GetEnemies(caster);
foreach (Character character in GamingQueue.Queue)
{
if (character.Effects.FirstOrDefault(e => e is ) is e)
{
e.DispelledType = DispelledType.CannotBeDispelled;
e.RemainDurationTurn = 3;
}
if (enemies.Contains(character))
{
Effect e2 = new (Skill, caster, character, this)
{
Durative = false,
DurationTurn = 3,
RemainDurationTurn = 3
};
character.Effects.Add(e2);
e2.OnEffectGained(character);
}
}
GamingQueue.LastRound.AddApplyEffects(caster, EffectType.Focusing);
}
GamingQueue?.LastRound.AddApplyEffects(caster, EffectType.CritBoost, EffectType.PenetrationBoost);
}
}
}

View File

@ -7,7 +7,11 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
public override long Id => (long)PassiveID.;
public override string Name => "概念之骰";
public override string Description => Effects.Count > 0 ? Effects.First().Description : "";
public override string Description => Effects.Count > 0 ? (()Effects.First()).GeneralDescription : "";
public int { get; set; } = 0;
public int { get; set; } = 0;
public int { get; set; } = 0;
public int { get; set; } = 0;
public (Character? character = null) : base(SkillType.Passive, character)
{
@ -18,29 +22,189 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
return Effects;
}
public override void OnCharacterRespawn(Skill newSkill)
{
if (newSkill is skill)
{
skill. = ;
skill. = ;
skill. = ;
skill. = ;
}
}
}
public class (Skill skill) : Effect(skill)
public class : Effect
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"{Skill.SkillOwner()}的每次行动决策结束时,都会为自身投掷一次概念骰子,获得一种增益且维持至下一次行动决策。\r\n" +
$"骰子效果(六面):\r\n" +
$"1.星辉:下次造成的伤害提升 30%。\r\n" +
$"2.壁垒:下次受到的伤害减少 30%。\r\n" +
$"3.流转:立即获得 50 点能量值。\r\n" +
$"4.预读:下次使用的主动技能冷却时间减少 40%。\r\n" +
$"5.共鸣:本次行动为全场所有其他角色(不论敌友)附加能量涟漪,使其下一次行动的能量消耗增加 20%。\r\n" +
$"6.干涉:随机使一名敌方角色身上的一个增益效果或一名友方角色身上的一个负面效果的持续时间延长或缩短 1 回合。";
public override string Description { get; set; } = "";
public string GeneralDescription => $"{Skill.SkillOwner()}的助攻窗口期永远不会过期。{Skill.SkillOwner()}每次参与击杀时都会进行一次概念投掷,获得一层永久持续的增益效果,且每个概念都最多可以叠加 {最多层数} 层。每次概念投掷可取得以下任意一项概念增益:\r\n" +
$"「力」:攻击力提升 {攻击力提升 * 100:0.##}% [ {Skill.Character?.BaseATK * 攻击力提升:0.##} ]。\r\n「暴」暴击率提升 {暴击率提升 * 100:0.##}%,暴击伤害提升 {暴击伤害提升 * 100:0.##}%。\r\n「噬」生命偷取提升 {生命偷取提升 * 100:0.##}%。\r\n「御」受到的伤害减少 {攻击力提升 * 100:0.##}%。\r\n" +
$"取得第一层「噬」后,同时获得「恒」效果:当总生命偷取超过 {生命偷取阈值 * 100:0.##}% 后,超出部分每 {生命偷取每单位 * 100:0.##}% 转化为 {生命偷取转化 * 100:0.##}% 攻击力。";
public static int => 8;
public static double => 0.08;
public static double => 0.04;
public static double => 0.08;
public static double => 0.05;
public static double => 0.06;
public static double => 0.3;
public static double => 0.01;
public static double => 0.005;
private double = 0;
private double = 0;
private double = 0;
private double = 0;
private double = 0;
private double = 0;
public (Skill skill) : base(skill)
{
Description = GeneralDescription;
}
public override double AlterActualDamageAfterCalculation(Character character, Character enemy, double damage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult, ref bool isEvaded, Dictionary<Effect, double> totalDamageBonus)
{
if (enemy == Skill.Character && > 0)
{
double reduce = damage * ;
WriteLine($"[ {Skill.Character} ] 发动了概念之骰!伤害减少了 {reduce:0.##} 点!");
return -reduce;
}
return 0;
}
public override void AfterDeathCalculation(Character death, Character? killer, Dictionary<Character, int> continuousKilling, Dictionary<Character, int> earnedMoney, Character[] assists)
{
if (Skill.Character != null && death != Skill.Character && (killer == Skill.Character || assists.Contains(Skill.Character)) && Skill is skill)
{
WriteLine($"[ {Skill.Character} ] 进行概念投掷:“此乃,神之概念。”");
bool result = false;
do
{
switch (Random.Shared.Next(4))
{
case 0:
if (skill. < )
{
skill.++;
WriteLine($"[ {Skill.Character} ] 获得了「力」概念效果,当前「力」层数:{skill.力层数}。");
result = true;
}
break;
case 1:
if (skill. < )
{
skill.++;
WriteLine($"[ {Skill.Character} ] 获得了「暴」概念效果,当前「暴」层数:{skill.暴层数}。");
result = true;
}
break;
case 2:
if (skill. < )
{
skill.++;
WriteLine($"[ {Skill.Character} ] 获得了「噬」概念效果,当前「噬」层数:{skill.噬层数}。");
result = true;
}
break;
case 3:
if (skill. < )
{
skill.++;
WriteLine($"[ {Skill.Character} ] 获得了「御」概念效果,当前「御」层数:{skill.御层数}。");
result = true;
}
break;
}
if (skill. + skill. + skill. + skill. >= * 4)
{
WriteLine($"[ {Skill.Character} ] 已经完成了「概念之骰」的全部概念收集!!");
result = true;
}
}
while (!result);
if (result)
{
(Skill.Character);
}
}
}
public override void OnEffectGained(Character character)
{
(character);
}
public override void OnEffectLost(Character character)
public override void OnTimeElapsed(Character character, double elapsed)
{
(character);
if (GamingQueue != null && GamingQueue.AssistDetails.TryGetValue(character, out AssistDetail? ad) && ad != null)
{
foreach (Character enemy in ad.DamageLastTime.Keys)
{
ad.DamageLastTime[enemy] = GamingQueue.TotalTime;
}
foreach (Character teammate in ad.NotDamageAssistLastTime.Keys)
{
ad.NotDamageAssistLastTime[teammate] = GamingQueue.TotalTime;
}
}
}
public void (Character character)
{
if ( != 0)
{
character.ExATKPercentage -= ;
= 0;
}
if ( != 0)
{
character.ExCritRate -= ;
= 0;
}
if ( != 0)
{
character.ExCritDMG -= ;
= 0;
}
if ( != 0)
{
character.Lifesteal -= ;
= 0;
}
if ( != 0)
{
= 0;
}
if ( != 0)
{
character.ExATKPercentage -= ;
= 0;
}
if (Skill is skill)
{
= * skill.;
= * skill.;
= * skill.;
= * skill.;
= * skill.;
character.ExATKPercentage += ;
character.ExCritRate += ;
character.ExCritDMG += ;
character.Lifesteal += ;
if (skill. > 0 && character.Lifesteal > )
{
double = character.Lifesteal - ;
= / * ;
}
character.ExATKPercentage += ;
Description = $"{Skill.SkillOwner()}的助攻窗口期永远不会过期。{Skill.SkillOwner()}每次参与击杀时都会进行一次概念投掷,获得一层永久持续的增益效果,且每个概念都最多可以叠加 {最多层数} 层。(当前层数:「力」× {skill.力层数}、「暴」× {skill.暴层数}、「噬」× {skill.噬层数}、「御」× {skill.御层数},攻击力提升:{(实际攻击力提升 + 实际生命偷取转化) * 100:0.##}% [ {character.BaseATK * (实际攻击力提升 + 实际生命偷取转化):0.##} ] 点,暴击率提升:{实际暴击率提升 * 100:0.##}%,暴击伤害提升:{实际暴击伤害提升 * 100:0.##}%,生命偷取提升:{实际生命偷取提升 * 100:0.##}%,受到伤害减少:{实际受到伤害减少 * 100:0.##}%";
}
}
}
}

View File

@ -27,22 +27,64 @@ namespace Oshima.FunGame.OshimaModules.Skills
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"{Skill.SkillOwner()}展开一个持续 3 回合的宏大领域,覆盖整个战场。在此领域内,一切必然都将被概率暂时覆盖。\r\n" +
$"领域规则一:命运共享。领域持续期间,所有角色(包括自身)的暴击率、闪避率将被暂时移除,替换为一个统一的命运值(初始为 50%)。每次进行相关检定时,都基于此命运值进行计算。\r\n" +
$"领域规则二:骰子指挥。{Skill.SkillOwner()}的每次行动前,可任意指定一名角色(不论敌友)进行一次强制骰子检定。\r\n" +
$"投掷结果将强制该角色执行以下行动之一:\r\n" +
$"1.攻击:攻击力提升 {攻击力提升 * 100:0.##}% 并随机对一名敌方角色进行普通攻击。\r\n" +
$"2.防御:{Skill.SkillOwner()}结束本回合并进入防御状态,下一次行动前,获得 {减伤提升 * 100:0.##}% 物理伤害减免和魔法抗性。\r\n" +
$"3.奉献治疗生命值百分比最低的一名角色治疗量为2d20 * {Skill.SkillOwner()} {智力系数 * 100:0.##}% 智力 [ {Skill.Character?.INT * 智力系数:0.##} ]。\r\n" +
$"4.混乱:对该角色周围造成一次 [ 6d{Skill.Level} * 60 ] 点真实伤害(不论敌友)。\r\n" +
$"完成强制骰子检定后,{Skill.SkillOwner()}可指定任意一名角色提升 10% 命运值。\r\n" +
$"领域规则三:观测奖励。领域持续期间,每当有角色因命运值检定成功(如闪避、暴击)或执行了强制骰子行动,{Skill.SkillOwner()}都会获得一层因果点。" +
$"领域结束时,每层因果点将转化为{Skill.SkillOwner()}对随机一名角色造成 [ 10d100 * 因果点 ] 的真实伤害(敌方)或治疗(友方)。";
public override string Description => $"{Skill.SkillOwner()}短暂显现其「神」之本质,开启持续 4 回合的「神之领域」:在持续时间内,{Skill.SkillOwner()}对任意敌方目标造成的伤害,都将记录为「因果伤害值」。" +
$"在持续时间结束后,所有敌方角色都会受到 [ 基于总因果伤害值的 600% 除以当前在场敌方角色数量 ] 的真实伤害。在持续时间内,{Skill.SkillOwner()}可以对任何负面效果进行豁免。" +
( > 0 ? $"(当前累计因果:{因果伤害值:0.##} 点)" : "");
public override DispelledType DispelledType => DispelledType.CannotBeDispelled;
public override bool Durative => false;
public override int DurationTurn => 4;
public double => 0.3 + 0.1 * (Skill.Level - 1);
public double => 0.2 + 0.08 * (Skill.Level - 1);
public double => 1.5 + 0.02 * (Skill.Level - 1);
public double { get; set; } = 0;
public override bool OnExemptionCheck(Character character, Character? source, Effect effect, bool isEvade, ref double throwingBonus)
{
if (character == Skill.Character)
{
throwingBonus += 300;
}
return true;
}
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{
if (character == Skill.Character && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical))
{
+= actualDamage;
}
}
public override void AfterDeathCalculation(Character death, Character? killer, Dictionary<Character, int> continuousKilling, Dictionary<Character, int> earnedMoney, Character[] assists)
{
if (death == Skill.Character)
{
= 0;
}
}
public override void OnEffectGained(Character character)
{
= 0;
}
public override void OnEffectLost(Character character)
{
if (GamingQueue != null && > 0)
{
WriteLine($"[ {character} ] 发动了神之因果!万象因果,命运既定!!!");
List<Character> enemies = [.. GamingQueue.GetEnemies(character).Where(GamingQueue.Queue.Contains)];
double damage = * 2 / enemies.Count;
foreach (Character enemy in enemies)
{
DamageToEnemy(character, enemy, DamageType.True, MagicType, damage, new()
{
CalculateShield = false,
IgnoreImmune = true,
TriggerEffects = false
});
}
= 0;
}
}
public override void OnSkillCasted(Character caster, List<Character> targets, List<Grid> grids, Dictionary<string, object> others)
{
@ -52,7 +94,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
caster.Effects.Add(this);
OnEffectGained(caster);
}
GamingQueue?.LastRound.AddApplyEffects(caster, EffectType.CritBoost, EffectType.PenetrationBoost);
GamingQueue?.LastRound.AddApplyEffects(caster, EffectType.Focusing);
}
}
}

View File

@ -30,8 +30,8 @@ namespace Oshima.FunGame.OshimaModules.Skills
public bool { get; set; } = false;
public bool { get; set; } = false;
public bool { get; set; } = false;
public double { get; set; } = 0.8;
public double { get; set; } = 0.4;
public double { get; set; } = 0.6;
public double { get; set; } = 0.3;
public double { get; set; } = 0.1;
public double { get; set; } = 0.3;
public double { get; set; } = 0.15;

View File

@ -49,7 +49,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
}
}
public override bool BeforeCriticalCheck(Character actor, Character enemy, ref double throwingBonus)
public override bool BeforeCriticalCheck(Character actor, Character enemy, bool isNormalAttack, ref double throwingBonus)
{
if (actor == Skill.Character)
{

View File

@ -2160,6 +2160,7 @@
{
"Id": 8032,
"exspd": 90,
"exmov": 1,
"exint2": 0.2
}
]
@ -2189,6 +2190,7 @@
{
"Id": 8032,
"exspd": 75,
"exmov": 1,
"excrd": 0.16
}
]
@ -2218,6 +2220,7 @@
{
"Id": 8032,
"exspd": 90,
"exmov": 1,
"exacc": 0.1
}
]
@ -2247,6 +2250,7 @@
{
"Id": 8032,
"exspd": 90,
"exmov": 1,
"exhr": 8
}
]
@ -2275,7 +2279,8 @@
"Effects": [
{
"Id": 8032,
"exspd": 120
"exspd": 120,
"exmov": 1
}
]
}
@ -2304,6 +2309,7 @@
{
"Id": 8032,
"exspd": 120,
"exmov": 1,
"excdr": 0.15
}
]
@ -2333,6 +2339,7 @@
{
"Id": 8032,
"exspd": 120,
"exmov": 1,
"exmr": 8
}
]
@ -2361,7 +2368,8 @@
"Effects": [
{
"Id": 8032,
"exspd": 160
"exspd": 160,
"exmov": 1
}
]
}
@ -2390,6 +2398,7 @@
{
"Id": 8032,
"exspd": 105,
"exmov": 1,
"excr": 0.15
}
]
@ -2419,6 +2428,7 @@
{
"Id": 8032,
"exspd": 120,
"exmov": 1,
"exmpt": 0.1
}
]
@ -2448,6 +2458,7 @@
{
"Id": 8032,
"exspd": 120,
"exmov": 1,
"exacc": 0.15
}
]
@ -2477,6 +2488,7 @@
{
"Id": 8032,
"exspd": 150,
"exmov": 2,
"mdftype": 0,
"mdfvalue": 0.1
}
@ -2506,7 +2518,8 @@
"Effects": [
{
"Id": 8032,
"exspd": 200
"exspd": 200,
"exmov": 2
}
]
}
@ -2535,6 +2548,7 @@
{
"Id": 8032,
"exspd": 135,
"exmov": 2,
"excrd": 0.3
}
]
@ -2564,6 +2578,7 @@
{
"Id": 8032,
"exspd": 150,
"exmov": 2,
"exstr": 10,
"exagi": 10,
"exint": 10
@ -2595,6 +2610,7 @@
{
"Id": 8032,
"exspd": 155,
"exmov": 2,
"exacc": 0.20
}
]
@ -2623,7 +2639,8 @@
"Effects": [
{
"Id": 8032,
"exspd": 240
"exspd": 240,
"exmov": 3
}
]
}
@ -2652,6 +2669,7 @@
{
"Id": 8032,
"exspd": 180,
"exmov": 3,
"exacc": 0.25
}
]
@ -2681,6 +2699,7 @@
{
"Id": 8032,
"exspd": 165,
"exmov": 3,
"excr": 0.22
}
]
@ -2710,6 +2729,7 @@
{
"Id": 8032,
"exspd": 165,
"exmov": 3,
"excrd": 0.44
}
]
@ -2739,6 +2759,7 @@
{
"Id": 8032,
"exspd": 180,
"exmov": 3,
"exstr": 15,
"exagi": 15,
"exint": 15

View File

@ -393,6 +393,13 @@ namespace Oshima.FunGame.OshimaServers.Service
nextDropTime -= timeLapse;
//Thread.Sleep(1);
if (actionQueue.GameOver)
{
result.Add(Msg);
lastRecord.Add(actionQueue.LastRound.ToString());
break;
}
if (roundMsg != "")
{
if ((isTeam && deathMatchRoundDetail || !isTeam) && isWeb)
@ -686,7 +693,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
}
private static bool ActionQueue_CharacterDeath(GamingQueue queue, Character current, Character death, Character[] assists)
private static bool ActionQueue_CharacterDeath(GamingQueue queue, Character death, Character? killer, Character[] assists)
{
death.Items.Clear();
return true;