添加ExATR、ExMOV适配战棋地图玩法,添加新的技能,平衡修复

This commit is contained in:
milimoe 2025-09-10 19:43:45 +08:00
parent 260d016972
commit 2ebcb10127
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
14 changed files with 300 additions and 17 deletions

View File

@ -175,6 +175,21 @@
/// </summary>
IgnoreEvade = 8033,
/// <summary>
/// 数值攻击距离参数exatr
/// </summary>
ExATR = 8034,
/// <summary>
/// 数值移动距离参数exmov
/// </summary>
ExMOV = 8035,
/// <summary>
/// 生命偷取%参数exls
/// </summary>
ExLifesteal = 8038,
/// <summary>
/// 被动特效终点
/// </summary>

View File

@ -582,6 +582,36 @@ namespace Oshima.FunGame.OshimaModules.Effects.OpenEffects
Descriptions.Add($"{(exls >= 0 ? "" : "")}角色 {Math.Abs(exls) * 100:0.##}% 生命偷取。");
}
break;
case "exatr":
if (int.TryParse(value, out int exatr))
{
if (!remove)
{
character.ExATR += exatr;
}
else if (RealDynamicsValues.TryGetValue("exatr", out double current))
{
character.ExATR -= (int)current;
}
RealDynamicsValues["exatr"] = exatr;
Descriptions.Add($"{(exatr >= 0 ? "" : "")}角色 {Math.Abs(exatr)} 格攻击距离。");
}
break;
case "exmov":
if (int.TryParse(value, out int exmov))
{
if (!remove)
{
character.ExMOV += exmov;
}
else if (RealDynamicsValues.TryGetValue("exmov", out double current))
{
character.ExMOV -= (int)current;
}
RealDynamicsValues["exmov"] = exmov;
Descriptions.Add($"{(exmov >= 0 ? "" : "")}角色 {Math.Abs(exmov)} 格移动距离。");
}
break;
}
}
}

View File

@ -0,0 +1,48 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Oshima.FunGame.OshimaModules.Effects.OpenEffects
{
public class ExATR : Effect
{
public override long Id => (long)EffectID.ExATR;
public override string Name => "攻击距离加成";
public override string Description => $"{(实际加成 >= 0 ? "" : "")}角色 {Math.Abs(实际加成)} 格攻击距离。" + (Source != null && (Skill.Character != Source || Skill is not OpenSkill) ? $"来自:[ {Source} ]" + (Skill.Item != null ? $" 的 [ {Skill.Item.Name} ]" : (Skill is OpenSkill ? "" : $" 的 [ {Skill.Name} ]")) : "");
public int Value => ;
private readonly int = 0;
public override void OnEffectGained(Character character)
{
if (Durative && RemainDuration == 0)
{
RemainDuration = Duration;
}
else if (RemainDurationTurn == 0)
{
RemainDurationTurn = DurationTurn;
}
character.ExATR += ;
}
public override void OnEffectLost(Character character)
{
character.ExATR -= ;
}
public ExATR(Skill skill, Dictionary<string, object> args, Character? source = null) : base(skill, args)
{
EffectType = EffectType.Item;
GamingQueue = skill.GamingQueue;
Source = source;
if (Values.Count > 0)
{
string key = Values.Keys.FirstOrDefault(s => s.Equals("exatr", StringComparison.CurrentCultureIgnoreCase)) ?? "";
if (key.Length > 0 && int.TryParse(Values[key].ToString(), out int exATR))
{
= exATR;
}
}
}
}
}

View File

@ -0,0 +1,48 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Oshima.FunGame.OshimaModules.Effects.OpenEffects
{
public class ExLifesteal : Effect
{
public override long Id => (long)EffectID.ExLifesteal;
public override string Name => "生命偷取加成";
public override string Description => $"{(实际加成 >= 0 ? "" : "")}角色 {Math.Abs(实际加成) * 100:0.##}% 生命偷取。" + (Source != null && (Skill.Character != Source || Skill is not OpenSkill) ? $"来自:[ {Source} ]" + (Skill.Item != null ? $" 的 [ {Skill.Item.Name} ]" : (Skill is OpenSkill ? "" : $" 的 [ {Skill.Name} ]")) : "");
public double Value => ;
private readonly double = 0;
public override void OnEffectGained(Character character)
{
if (Durative && RemainDuration == 0)
{
RemainDuration = Duration;
}
else if (RemainDurationTurn == 0)
{
RemainDurationTurn = DurationTurn;
}
character.Lifesteal += ;
}
public override void OnEffectLost(Character character)
{
character.Lifesteal -= ;
}
public ExLifesteal(Skill skill, Dictionary<string, object> args, Character? source = null) : base(skill, args)
{
EffectType = EffectType.Item;
GamingQueue = skill.GamingQueue;
Source = source;
if (Values.Count > 0)
{
string key = Values.Keys.FirstOrDefault(s => s.Equals("exls", StringComparison.CurrentCultureIgnoreCase)) ?? "";
if (key.Length > 0 && double.TryParse(Values[key].ToString(), out double exLS))
{
= exLS;
}
}
}
}
}

View File

@ -0,0 +1,48 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Oshima.FunGame.OshimaModules.Effects.OpenEffects
{
public class ExMOV : Effect
{
public override long Id => (long)EffectID.ExMOV;
public override string Name => "移动距离加成";
public override string Description => $"{(实际加成 >= 0 ? "" : "")}角色 {Math.Abs(实际加成)} 格移动距离。" + (Source != null && (Skill.Character != Source || Skill is not OpenSkill) ? $"来自:[ {Source} ]" + (Skill.Item != null ? $" 的 [ {Skill.Item.Name} ]" : (Skill is OpenSkill ? "" : $" 的 [ {Skill.Name} ]")) : "");
public int Value => ;
private readonly int = 0;
public override void OnEffectGained(Character character)
{
if (Durative && RemainDuration == 0)
{
RemainDuration = Duration;
}
else if (RemainDurationTurn == 0)
{
RemainDurationTurn = DurationTurn;
}
character.ExMOV += ;
}
public override void OnEffectLost(Character character)
{
character.ExMOV -= ;
}
public ExMOV(Skill skill, Dictionary<string, object> args, Character? source = null) : base(skill, args)
{
EffectType = EffectType.Item;
GamingQueue = skill.GamingQueue;
Source = source;
if (Values.Count > 0)
{
string key = Values.Keys.FirstOrDefault(s => s.Equals("exmov", StringComparison.CurrentCultureIgnoreCase)) ?? "";
if (key.Length > 0 && int.TryParse(Values[key].ToString(), out int exMOV))
{
= exMOV;
}
}
}
}
}

View File

@ -170,6 +170,7 @@ namespace Oshima.FunGame.OshimaModules.Items
{
Level = 1;
Item = item;
SelectTargetPredicates.Add(c => c.HP > 0 && c.HP < c.MaxHP);
if (!isPercentage)
{
Effects.Add(new RecoverHP(this, new()

View File

@ -166,6 +166,7 @@ namespace Oshima.FunGame.OshimaModules.Items
_canSelectTeammate = canSelectTeammate;
_canSelectEnemy = canSelectEnemy;
_canSelectCount = canSelectCount;
SelectTargetPredicates.Add(c => c.HP >= 0 && c.HP < c.MaxHP);
Effects.Add(new (this));
if (!isPercentage)
{

View File

@ -22,7 +22,9 @@ namespace Oshima.FunGame.OshimaModules.Models
public static List<Character> Characters { get; } = [];
public static List<Skill> Skills { get; } = [];
public static List<Skill> PassiveSkills { get; } = [];
public static List<Skill> CommonPassiveSkills { get; } = [];
public static List<Skill> SuperSkills { get; } = [];
public static List<Skill> CommonSuperSkills { get; } = [];
public static List<Skill> Magics { get; } = [];
public static List<Item> Equipment { get; } = [];
public static List<Item> Items { get; } = [];
@ -47,7 +49,6 @@ namespace Oshima.FunGame.OshimaModules.Models
public static Dictionary<long, double> UserCreditsRanking { get; } = [];
public static Dictionary<long, double> UserMaterialsRanking { get; } = [];
public static Dictionary<long, double> UserEXPRanking { get; } = [];
public static Dictionary<long, double> UserSkillRanking { get; } = [];
public static Dictionary<long, Club> ClubIdAndClub { get; } = [];
public static DateTime RankingUpdateTime { get; set; } = DateTime.Now;
public static char[] SplitChars => [',', ' ', '', '', ';'];
@ -300,6 +301,13 @@ namespace Oshima.FunGame.OshimaModules.Models
{ "exatk", Math.Clamp(Random.Shared.NextDouble(), 0.15, 0.3) }
}
},
{
EffectID.ExMaxMP2,
new()
{
{ "exmp", 5 }
}
},
{
EffectID.AccelerationCoefficient,
new()

View File

@ -124,6 +124,8 @@ namespace Oshima.FunGame.OshimaModules
(long)PassiveID. => new (),
(long)PassiveID. => new (),
(long)PassiveID. => new (),
(long)PassiveID. => new (),
(long)PassiveID. => new (),
(long)ItemPassiveID. => new (),
(long)ItemActiveID. => new (),
(long)ItemActiveID. => new (),
@ -173,6 +175,9 @@ namespace Oshima.FunGame.OshimaModules
EffectID.ExMaxMP2 => new ExMaxMP2(skill, dict),
EffectID.DynamicsEffect => new DynamicsEffect(skill, dict),
EffectID.IgnoreEvade => new IgnoreEvade(skill, dict),
EffectID.ExATR => new ExATR(skill, dict),
EffectID.ExMOV => new ExMOV(skill, dict),
EffectID.ExLifesteal => new ExLifesteal(skill, dict),
EffectID.RecoverHP => new RecoverHP(skill, dict),
EffectID.RecoverMP => new RecoverMP(skill, dict),
EffectID.RecoverHP2 => new RecoverHP2(skill, dict),

View File

@ -0,0 +1,81 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
namespace Oshima.FunGame.OshimaModules.Skills
{
public class : Skill
{
public override long Id => (long)PassiveID.;
public override string Name => "致命节奏";
public override string Description => Effects.Count > 0 ? Effects.First().Description : "";
public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : "";
public (Character? character = null) : base(SkillType.Passive, character)
{
Effects.Add(new (this));
}
public override IEnumerable<Effect> AddPassiveEffectToCharacter()
{
return Effects;
}
}
public class (Skill skill) : Effect(skill)
{
public override long Id => Skill.Id;
public override string Name => Skill.Name;
public override string Description => $"每次普通攻击造成伤害后,提升 {行动速度提升:0.##} 点行动速度,持续 {行动速度持续时间:0.##} {GameplayEquilibriumConstant.InGameTime}。" +
$"当行动系数达到 {行动系数阈值:0.##}% 时,获得 {额外攻击力:0.##} 点额外攻击力,持续 {额外攻击力持续时间:0.##} {GameplayEquilibriumConstant.InGameTime}。" +
$"获得额外攻击力后,致命节奏进入冷却时间 {冷却时间} {GameplayEquilibriumConstant.InGameTime}。";
private double => Skill.Character != null ? 25 + Skill.Character.Level * 0.6 : 25;
private double => Skill.Character != null ? 18 - Skill.Character.Level * 0.1 : 18;
private double => Skill.Character != null ? 40 + Skill.Character.Level * 1.1 : 40;
private double => Skill.Character != null ? 12 + Skill.Character.Level * 0.15 : 12;
private double => Skill.Character != null ? 6 + Skill.Character.Level * 1.7 : 6;
private double => Skill.Character != null ? 24 + Skill.Character.Level * 0.1 : 24;
private bool => Skill.CurrentCD > 0;
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{
if (Skill.Character != null && Skill.Character == character && ! && isNormalAttack && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical))
{
WriteLine($"[ {character} ] 发动了致命节奏,提升了 {行动速度提升:0.##} 点行动速度!");
Effect e1 = new ExSPD(Skill, new Dictionary<string, object>()
{
{ "exspd", }
}, character)
{
Durative = true,
Duration =
};
character.Effects.Add(e1);
e1.OnEffectGained(character);
e1.IsDebuff = false;
RecordCharacterApplyEffects(character, EffectType.Haste);
// 检查是否达到阈值
if (character.ActionCoefficient * 100 >= )
{
Skill.Enable = false;
Skill.CurrentCD = ;
WriteLine($"[ {character} ] 发动了致命节奏,获得了 {额外攻击力:0.##} 点额外攻击力!");
Effect e2 = new ExATK(Skill, new Dictionary<string, object>()
{
{ "exatk", }
}, character)
{
Durative = true,
Duration =
};
character.Effects.Add(e2);
e2.OnEffectGained(character);
e2.IsDebuff = false;
RecordCharacterApplyEffects(character, EffectType.DamageBoost);
}
}
}
}
}

View File

@ -1,7 +1,6 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
using Oshima.FunGame.OshimaModules.Effects.SkillEffects;
namespace Oshima.FunGame.OshimaModules.Skills
{
@ -109,7 +108,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
target.Effects.Add(e2);
e2.OnEffectGained(target);
e2.IsDebuff = false;
GamingQueue?.LastRound.ApplyEffects.TryAdd(target, [EffectType.Haste]);
RecordCharacterApplyEffects(target, EffectType.Haste);
}
}
}

View File

@ -1,7 +1,6 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
using Oshima.FunGame.OshimaModules.Effects.SkillEffects;
namespace Oshima.FunGame.OshimaModules.Skills
{
@ -10,10 +9,10 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override long Id => (long)MagicID.;
public override string Name => "时间加速·改";
public override string Description => Effects.Count > 0 ? Effects.First().Description : "";
public override double MPCost => Level > 0 ? 80 + (85 * (Level - 1)) : 80;
public override double MPCost => Level > 0 ? 120 + (115 * (Level - 1)) : 120;
public override double CD => Level > 0 ? 65 - (0.5 * (Level - 1)) : 65;
public override double CastTime => Level > 0 ? 6 + (1 * (Level - 1)) : 6;
public override double HardnessTime { get; set; } = 7;
public override double CastTime => 3;
public override double HardnessTime { get; set; } = 9;
public override bool CanSelectSelf => true;
public override bool CanSelectTeammate => true;
public override bool CanSelectEnemy => false;
@ -93,7 +92,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
target.Effects.Add(e2);
e2.OnEffectGained(target);
e2.IsDebuff = false;
GamingQueue?.LastRound.ApplyEffects.TryAdd(target, [EffectType.Haste]);
RecordCharacterApplyEffects(target, EffectType.Haste);
}
}
}

View File

@ -51,6 +51,8 @@ namespace Oshima.FunGame.OshimaServers.Service
FunGameConstant.SuperSkills.AddRange([new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new ()]);
FunGameConstant.PassiveSkills.AddRange([new META马(), new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new ()]);
FunGameConstant.CommonPassiveSkills.AddRange([new (), new ()]);
FunGameConstant.Magics.AddRange([new (), new (), new (), new (), new (), new (), new (), new (),
new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new (),
@ -126,8 +128,10 @@ namespace Oshima.FunGame.OshimaServers.Service
FunGameConstant.AllSkills.AddRange(FunGameConstant.Magics);
FunGameConstant.AllSkills.AddRange(FunGameConstant.Skills);
FunGameConstant.AllSkills.AddRange(FunGameConstant.PassiveSkills);
FunGameConstant.AllSkills.AddRange(FunGameConstant.CommonPassiveSkills);
FunGameConstant.AllSkills.AddRange(FunGameConstant.ItemSkills);
FunGameConstant.AllSkills.AddRange(FunGameConstant.SuperSkills);
FunGameConstant.AllSkills.AddRange(FunGameConstant.CommonSuperSkills);
}
public static List<Item> GenerateMagicCards(int count, QualityType? qualityType = null, long[]? magicIds = null, (int str, int agi, int intelligence)[]? values = null)
@ -460,7 +464,9 @@ namespace Oshima.FunGame.OshimaServers.Service
FunGameConstant.Equipment.Clear();
FunGameConstant.Skills.Clear();
FunGameConstant.SuperSkills.Clear();
FunGameConstant.CommonSuperSkills.Clear();
FunGameConstant.PassiveSkills.Clear();
FunGameConstant.CommonPassiveSkills.Clear();
FunGameConstant.Magics.Clear();
FunGameConstant.DrawCardItems.Clear();
FunGameConstant.ExploreItems.Clear();
@ -1751,7 +1757,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
// 存活时间贡献
double liveTimeContribution = Math.Log(1 + (stats.LiveTime / (stats.TotalTakenDamage + 0.01) * 100));
double liveTimeContribution = Math.Log(1 + (stats.LiveTime / (stats.TotalTakenDamage + 1) * 100));
// 团队模式参团率加成
double teamContribution = 0;
@ -4588,8 +4594,7 @@ namespace Oshima.FunGame.OshimaServers.Service
// 排行榜更新
FunGameConstant.UserCreditsRanking[user.Id] = user.Inventory.Credits;
FunGameConstant.UserMaterialsRanking[user.Id] = user.Inventory.Materials;
FunGameConstant.UserEXPRanking[user.Id] = user.Inventory.Characters.Select(c => FunGameConstant.PrecomputeTotalExperience[c.Level] + c.EXP).Sum();
FunGameConstant.UserSkillRanking[user.Id] = user.Inventory.Characters.Select(c => (c.NormalAttack.Level - 1) * 50000 + c.Skills.Select(s => s.Level * 40000).Sum()).Sum();
FunGameConstant.UserEXPRanking[user.Id] = user.Inventory.Characters.Select(c => FunGameConstant.PrecomputeTotalExperience[c.Level] + c.EXP + (c.NormalAttack.Level - 1) * 50000 + c.Skills.Select(s => s.Level * 40000).Sum()).Sum();
if (pc.TryGetValue("horseRacingPoints", out object? value3) && int.TryParse(value3.ToString(), out int horseRacingPoints))
{
FunGameConstant.UserHorseRacingRanking[user.Id] = horseRacingPoints;

View File

@ -8690,12 +8690,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
{
currentTop = index + 1;
}
double score = kv.Value;
if (FunGameConstant.UserSkillRanking.TryGetValue(kv.Key, out double value2))
{
score += value2;
}
return $"{index + 1}. UID{kv.Key},昵称:{username},总得分:{score:0.##}";
return $"{index + 1}. UID{kv.Key},昵称:{username},总得分:{kv.Value:0.##}";
})) : "暂无任何数据。")}\r\n\r\n本榜单统计角色的经验值总额\r\n仅显示前 {showTop} {(currentTop > 0 ? $",你目前排在第 {currentTop} 位。" : "")}",
3 => $"【赛马积分排行榜】\r\n" +
$"数据每分钟更新一次,上次更新:{FunGameConstant.RankingUpdateTime.ToString(General.GeneralDateTimeFormatChinese)}\r\n" +