技能测试!

This commit is contained in:
milimoe 2024-09-08 02:34:47 +08:00
parent 0667758c29
commit 195f9497d4
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
9 changed files with 516 additions and 225 deletions

View File

@ -0,0 +1,309 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace FunGame.Testing.Characters
{
public class Characters
{
public static Character Oshima
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Oshima";
c.FirstName = "Shiya";
c.NickName = "大島シヤ";
c.PrimaryAttribute = PrimaryAttribute.STR;
c.InitialATK = 25;
c.InitialHP = 160;
c.InitialMP = 10;
c.InitialSTR = 35;
c.STRGrowth = 3.5;
c.InitialAGI = 0;
c.AGIGrowth = 0;
c.InitialINT = 0;
c.INTGrowth = 0;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character Xinyin
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Xiyue";
c.FirstName = "XinYin";
c.NickName = "心音";
c.PrimaryAttribute = PrimaryAttribute.AGI;
c.InitialATK = 22;
c.InitialHP = 80;
c.InitialMP = 60;
c.InitialSTR = 8;
c.STRGrowth = 0.9;
c.InitialAGI = 19;
c.AGIGrowth = 1.7;
c.InitialINT = 3;
c.INTGrowth = 0.4;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character Yang
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Ya";
c.FirstName = "Yang";
c.NickName = "吖养";
c.PrimaryAttribute = PrimaryAttribute.STR;
c.InitialATK = 23;
c.InitialHP = 105;
c.InitialMP = 55;
c.InitialSTR = 11;
c.STRGrowth = 1.8;
c.InitialAGI = 9;
c.AGIGrowth = 0.5;
c.InitialINT = 10;
c.INTGrowth = 0.7;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character NanGanyu
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Nan";
c.FirstName = "Ganyu";
c.NickName = "男甘雨";
c.PrimaryAttribute = PrimaryAttribute.INT;
c.InitialATK = 17;
c.InitialHP = 115;
c.InitialMP = 80;
c.InitialSTR = 6;
c.STRGrowth = 0.6;
c.InitialAGI = 7;
c.AGIGrowth = 0.7;
c.InitialINT = 17;
c.INTGrowth = 0.7;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character NiuNan
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Niu";
c.FirstName = "Nan";
c.NickName = "牛腩";
c.PrimaryAttribute = PrimaryAttribute.INT;
c.InitialATK = 16;
c.InitialHP = 75;
c.InitialMP = 90;
c.InitialSTR = 0;
c.STRGrowth = 0;
c.InitialAGI = 0;
c.AGIGrowth = 0;
c.InitialINT = 30;
c.INTGrowth = 3;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character Mayor
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Dokyo";
c.FirstName = "Mayor";
c.NickName = "铎京市长";
c.PrimaryAttribute = PrimaryAttribute.AGI;
c.InitialATK = 21;
c.InitialHP = 120;
c.InitialMP = 20;
c.InitialSTR = 7;
c.STRGrowth = 1;
c.InitialAGI = 21;
c.AGIGrowth = 1.8;
c.InitialINT = 2;
c.INTGrowth = 0.2;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Magical";
c.FirstName = "Girl";
c.NickName = "魔法少女";
c.PrimaryAttribute = PrimaryAttribute.AGI;
c.InitialATK = 20;
c.InitialHP = 95;
c.InitialMP = 35;
c.InitialSTR = 7;
c.STRGrowth = 0.3;
c.InitialAGI = 15;
c.AGIGrowth = 2.3;
c.InitialINT = 8;
c.INTGrowth = 0.4;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character QingXiang
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Qing";
c.FirstName = "Xiang";
c.NickName = "清香";
c.PrimaryAttribute = PrimaryAttribute.INT;
c.InitialATK = 26;
c.InitialHP = 110;
c.InitialMP = 80;
c.InitialSTR = 6;
c.STRGrowth = 0.5;
c.InitialAGI = 4;
c.AGIGrowth = 0.5;
c.InitialINT = 20;
c.INTGrowth = 2;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character QWQAQW
{
get
{
Character c = Factory.GetCharacter();
c.Name = "QWQ";
c.FirstName = "AQW";
c.NickName = "LUOLI66";
c.PrimaryAttribute = PrimaryAttribute.INT;
c.InitialATK = 18;
c.InitialHP = 85;
c.InitialMP = 45;
c.InitialSTR = 0;
c.STRGrowth = 0;
c.InitialAGI = 15;
c.AGIGrowth = 1.5;
c.InitialINT = 15;
c.INTGrowth = 1.5;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character ColdBlue
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Cold";
c.FirstName = "Blue";
c.NickName = "冷蓝";
c.PrimaryAttribute = PrimaryAttribute.STR;
c.InitialATK = 28;
c.InitialHP = 135;
c.InitialMP = 25;
c.InitialSTR = 22;
c.STRGrowth = 1.9;
c.InitialAGI = 4;
c.AGIGrowth = 0.6;
c.InitialINT = 4;
c.INTGrowth = 0.6;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character 绿
{
get
{
Character c = Factory.GetCharacter();
c.Name = "ddd";
c.FirstName = "ovo";
c.NickName = "绿拱门";
c.PrimaryAttribute = PrimaryAttribute.AGI;
c.InitialATK = 22;
c.InitialHP = 65;
c.InitialMP = 22;
c.InitialSTR = 10;
c.STRGrowth = 1;
c.InitialAGI = 20;
c.AGIGrowth = 2;
c.InitialINT = 0;
c.INTGrowth = 0;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
public static Character QuDuoduo
{
get
{
Character c = Factory.GetCharacter();
c.Name = "Qu";
c.FirstName = "Duoduo";
c.NickName = "趣多多";
c.PrimaryAttribute = PrimaryAttribute.STR;
c.InitialATK = 19;
c.InitialHP = 90;
c.InitialMP = 40;
c.InitialSTR = 13;
c.STRGrowth = 1.5;
c.InitialAGI = 13;
c.AGIGrowth = 1.2;
c.InitialINT = 4;
c.INTGrowth = 0.3;
c.InitialSPD = 300;
c.InitialHR = 4;
c.InitialMR = 2;
return c;
}
}
}
}

View File

@ -0,0 +1,39 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Testing.Effects
{
public class (Skill skill) : Effect(skill)
{
public override long Id => 1;
public override string Name => "冰霜攻击";
public override string Description => $"对目标敌人造成 120%(+180%/Lv) + 250%智力 [ {Damage} ] 点元素魔法伤害。";
public override bool TargetSelf => false;
public override int TargetCount => 1;
public override MagicType MagicType => MagicType.Element;
private double Damage
{
get
{
double d = 0;
if (Skill.Character != null)
{
d = Calculation.Round2Digits(1.2 * (1 + 1.8 * (Skill.Level - 1)) * Skill.Character.ATK + (Skill.Character.INT * 2.5));
}
return d;
}
}
public override void OnSkillCasted(ActionQueue queue, Character actor, List<Character> enemys, List<Character> teammates, Dictionary<string, object> others)
{
Character enemy = enemys[new Random().Next(enemys.Count)];
double damageBase = Damage;
if (queue.CalculateMagicalDamage(actor, enemy, false, MagicType, damageBase, out double damage) != DamageResult.Evaded)
{
queue.DamageToEnemy(actor, enemy, damage, false, true, MagicType);
}
}
}
}

View File

@ -0,0 +1,67 @@
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Testing.Effects
{
public class (Skill skill) : Effect(skill)
{
public override long Id => 1;
public override string Name => "天赐之力";
public override string Description => $"{Duration} 时间内,获得 25% 闪避率,普通攻击硬直时间额外减少 20%,基于 120%+60%/Lv核心属性 [ {伤害加成} ] 强化普通攻击的伤害。";
public override bool TargetSelf => false;
public override int TargetCount => 1;
public override bool Durative => true;
public override double Duration => 40;
public override MagicType MagicType => MagicType.Element;
private double
{
get
{
double d = 0;
if (Skill.Character != null)
{
d = Calculation.Round2Digits(1.2 * (1 + 0.6 * (Skill.Level - 1)) * Skill.Character.PrimaryAttributeValue);
}
return d;
}
}
public override void OnEffectGained(Character character)
{
character.ExEvadeRate += 0.25;
}
public override void OnEffectLost(Character character)
{
character.ExEvadeRate -= 0.25;
}
public override bool AlterExpectedDamageBeforeCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, out double newDamage)
{
newDamage = damage;
if (isNormalAttack)
{
newDamage = Calculation.Round2Digits(damage + );
}
return true;
}
public override bool AlterHardnessTimeAfterNormalAttack(Character character, double baseHardnessTime, out double newHardnessTime)
{
newHardnessTime = Calculation.Round2Digits(baseHardnessTime * 0.8);
return true;
}
public override void OnSkillCasted(ActionQueue queue, Character actor, List<Character> enemys, List<Character> teammates, Dictionary<string, object> others)
{
if (!actor.Effects.ContainsKey(Name))
{
actor.Effects.Add(Name, this);
RemainDuration = Duration;
OnEffectGained(actor);
}
}
}
}

View File

@ -3,7 +3,7 @@ using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Common.Event;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Testing.Solutions; using Milimoe.FunGame.Testing.Skills;
PluginLoader plugins = PluginLoader.LoadPlugins([]); PluginLoader plugins = PluginLoader.LoadPlugins([]);
foreach (string plugin in plugins.Plugins.Keys) foreach (string plugin in plugins.Plugins.Keys)
@ -67,34 +67,65 @@ if (list.Count > 3)
Character character2 = list[1].Copy(); Character character2 = list[1].Copy();
Character character3 = list[2].Copy(); Character character3 = list[2].Copy();
Character character4 = list[3].Copy(); Character character4 = list[3].Copy();
Character character5 = list[4].Copy();
Character character6 = list[5].Copy();
Character character7 = list[6].Copy();
Character character8 = list[7].Copy();
Character character9 = list[8].Copy();
Character character10 = list[9].Copy();
Character character11 = list[10].Copy();
Character character12 = list[11].Copy();
ActionQueue actionQueue = new(); List<Character> characters = [
List<Character> characters = [character1, character2, character3, character4]; character1, character2, character3, character4,
character5, character6, character7, character8,
character9, character10, character11, character12
];
// 初始顺序表排序 // 升级和赋能
actionQueue.CalculateInitialOrder(characters); for (int index = 0; index < characters.Count; index++)
{
characters[index].Level = 60;
characters[index].Skills.Add("冰霜攻击", new (characters[index]));
characters[index].Skills["冰霜攻击"].Level += 8;
characters[index].Skills.Add("天赐之力", new (characters[index]));
characters[index].Skills["天赐之力"].Level += 6;
}
// 显示角色信息
characters.ForEach(c => Console.WriteLine(c.GetInfo()));
// 创建顺序表并排序
ActionQueue actionQueue = new(characters, Console.WriteLine);
Console.WriteLine(); Console.WriteLine();
// 显示初始顺序表 // 显示初始顺序表
actionQueue.DisplayQueue(); actionQueue.DisplayQueue();
Console.WriteLine(); Console.WriteLine();
// 模拟时间流逝 // 总回合数
int i = 1; int i = 1;
while (i < 10) while (i < 999)
{ {
// 检查是否有角色可以行动 // 检查是否有角色可以行动
Character? characterToAct = actionQueue.NextCharacter(); Character? characterToAct = actionQueue.NextCharacter();
if (characterToAct != null) if (characterToAct != null)
{ {
Console.WriteLine($"=== Round {i++} ==="); Console.WriteLine($"=== Round {i++} ===");
actionQueue.ProcessTurn(characterToAct); Console.WriteLine("现在是 [ " + characterToAct + " ] 的回合!");
bool isGameEnd = actionQueue.ProcessTurn(characterToAct);
if (isGameEnd)
{
break;
}
actionQueue.DisplayQueue(); actionQueue.DisplayQueue();
Console.WriteLine(); Console.WriteLine();
} }
//Thread.Sleep(1); // 模拟时间流逝 // 模拟时间流逝
actionQueue.ReduceHardnessTimes(); actionQueue.TimeLapse();
} }
Console.WriteLine("--- End ---"); Console.WriteLine("--- End ---");

View File

@ -0,0 +1,22 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Testing.Effects;
namespace Milimoe.FunGame.Testing.Skills
{
public class : Skill
{
public override long Id => 1;
public override string Name => "冰霜攻击";
public override string Description => Effects.Count > 0 ? Effects.Values.First().Description : "";
public override double MPCost => BaseMPCost + (50 * (Level - 1));
public override double CD => 20;
public override double CastTime => 6;
public override double HardnessTime => 3;
protected override double BaseMPCost => 30;
public (Character character) : base(true, true, character)
{
Effects.Add("e1", new (this));
}
}
}

View File

@ -0,0 +1,20 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Testing.Effects;
namespace Milimoe.FunGame.Testing.Skills
{
public class : Skill
{
public override long Id => 1;
public override string Name => "天赐之力";
public override string Description => Effects.Count > 0 ? Effects.Values.First().Description : "";
public override double EPCost => 100;
public override double CD => 60;
public override double HardnessTime => 15;
public (Character character) : base(true, character)
{
Effects.Add("e1", new (this));
}
}
}

View File

@ -1,157 +0,0 @@
using Milimoe.FunGame.Core.Entity;
namespace Milimoe.FunGame.Testing.Solutions;
public class ActionQueue
{
private readonly List<Character> _Queue = [];
private readonly Dictionary<Character, double> _HardnessTimes = [];
public void AddCharacter(Character character, double hardnessTime)
{
// 插队机制:按硬直时间排序
int insertIndex = _Queue.FindIndex(c => _HardnessTimes[c] > hardnessTime);
if (insertIndex == -1)
{
_Queue.Add(character);
}
else
{
_Queue.Insert(insertIndex, character);
}
_HardnessTimes[character] = hardnessTime;
}
public void CalculateInitialOrder(List<Character> characters)
{
// 排序时,时间会流逝
int nowTime = 1;
// 初始排序:按速度排序
List<IGrouping<double, Character>> groupedBySpeed = [.. characters
.GroupBy(c => c.SPD)
.OrderByDescending(g => g.Key)];
Random random = new();
foreach (IGrouping<double, Character> group in groupedBySpeed)
{
if (group.Count() == 1)
{
// 如果只有一个角色,直接加入队列
AddCharacter(group.First(), _Queue.Count + nowTime);
}
else
{
// 如果有多个角色,进行先行决定
List<Character> sortedList = [.. group];
while (sortedList.Count > 0)
{
Character? selectedCharacter = null;
bool decided = false;
if (sortedList.Count == 1)
{
selectedCharacter = sortedList[0];
decided = true;
}
while (!decided)
{
// 每个角色进行两次随机数抽取
var randomNumbers = sortedList.Select(c => new
{
Character = c,
FirstRoll = random.Next(1, 21),
SecondRoll = random.Next(1, 21)
}).ToList();
randomNumbers.ForEach(a => Console.WriteLine(a.Character.Name + ": " + a.FirstRoll + " / " + a.SecondRoll));
nowTime++;
// 找到两次都大于其他角色的角色
int maxFirstRoll = randomNumbers.Max(r => r.FirstRoll);
int maxSecondRoll = randomNumbers.Max(r => r.SecondRoll);
var candidates = randomNumbers
.Where(r => r.FirstRoll == maxFirstRoll && r.SecondRoll == maxSecondRoll)
.ToList();
if (candidates.Count == 1)
{
selectedCharacter = candidates.First().Character;
decided = true;
}
}
// 将决定好的角色加入顺序表
if (selectedCharacter != null)
{
AddCharacter(selectedCharacter, _Queue.Count + nowTime);
Console.WriteLine("decided: " + selectedCharacter.Name + "\r\n");
sortedList.Remove(selectedCharacter);
}
}
}
}
}
public Character? NextCharacter()
{
if (_Queue.Count == 0) return null;
// 硬直时间为0的角色将执行行动
Character? character = _Queue.FirstOrDefault(c => _HardnessTimes[c] == 0);
if (character != null)
{
_Queue.Remove(character);
return character;
}
return null;
}
public void ProcessTurn(Character character)
{
double baseTime = 15; // 假设基础硬直时间为15
if (character.Name == "A")
{
baseTime = 10; // A的硬直
}
double newHardnessTime = Math.Round(baseTime * (1 - character.ActionCoefficient), 2, MidpointRounding.AwayFromZero);
AddCharacter(character, newHardnessTime);
}
public void ReduceHardnessTimes()
{
if (_Queue.Count == 0) return;
// 获取第一个角色的硬直时间
double timeToReduce = _HardnessTimes[_Queue[0]];
Console.WriteLine("Time Lapse: " + timeToReduce);
// 减少所有角色的硬直时间
foreach (Character character in _Queue)
{
_HardnessTimes[character] = Math.Round(_HardnessTimes[character] - timeToReduce, 2, MidpointRounding.AwayFromZero);
// 回血回蓝
double douHP = Math.Round(character.HR * timeToReduce, 2, MidpointRounding.AwayFromZero);
double douMP = Math.Round(character.MR * timeToReduce, 2, MidpointRounding.AwayFromZero);
Console.WriteLine("角色 " + character.Name + " 回血:" + douHP + " / " + "回蓝:" + douMP);
}
Console.WriteLine();
}
public void DisplayQueue()
{
Console.WriteLine("Current ActionQueue:");
foreach (var character in _Queue)
{
Console.WriteLine($"{character.Name}: Hardness Time {_HardnessTimes[character]}");
}
}
}

View File

@ -1,7 +1,6 @@
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
namespace Addons namespace Addons
{ {
@ -51,7 +50,6 @@ namespace Addons
List<Skill> list = []; List<Skill> list = [];
Skill s = Factory.GetSkill(); Skill s = Factory.GetSkill();
s.Name = "Example Skill"; s.Name = "Example Skill";
s.MagicType = MagicType.PurityNatural;
list.Add(s); list.Add(s);
return list; return list;
} }

View File

@ -1,9 +1,9 @@
using Milimoe.FunGame.Core.Api.Utility; using FunGame.Testing.Characters;
using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface; using Milimoe.FunGame.Core.Interface;
using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Event; using Milimoe.FunGame.Core.Library.Common.Event;
using Milimoe.FunGame.Core.Library.Constant;
namespace Addons namespace Addons
{ {
@ -19,60 +19,22 @@ namespace Addons
protected override bool BeforeLoad() protected override bool BeforeLoad()
{ {
EntityModuleConfig<Character> config = new(ExampleGameModuleConstant.Example, ExampleGameModuleConstant.ExampleCharacter); EntityModuleConfig<Character> config = new(ExampleGameModuleConstant.Example, ExampleGameModuleConstant.ExampleCharacter)
// 构建一个你想要的角色 {
Character c = Factory.GetCharacter(); { "Oshima", Characters.Oshima },
c.Name = "Oshima"; { "Xinyin", Characters.Xinyin },
c.FirstName = "Shiya"; { "Yang", Characters.Yang },
c.NickName = "OSM"; { "NanGanyu", Characters.NanGanyu },
c.MagicType = MagicType.PurityNatural; { "NiuNan", Characters.NiuNan },
c.InitialHP = 30; { "Mayor", Characters.Mayor },
c.InitialSTR = 20; { "马猴烧酒", Characters. },
c.InitialAGI = 10; { "QingXiang", Characters.QingXiang },
c.InitialINT = 5; { "QWQAQW", Characters.QWQAQW },
c.InitialATK = 100; { "ColdBlue", Characters.ColdBlue },
c.InitialDEF = 10; { "绿拱门", Characters.绿 },
c.InitialSPD = 250; { "QuDuoduo", Characters.QuDuoduo }
config.Add("OSM", c); };
c = Factory.GetCharacter();
c.Name = "A";
c.FirstName = "测试1";
c.NickName = "A";
c.MagicType = MagicType.Particle;
c.InitialHP = 25;
c.InitialSTR = 15;
c.InitialAGI = 5;
c.InitialINT = 10;
c.InitialATK = 80;
c.InitialDEF = 15;
c.InitialSPD = 290;
config.Add("A", c);
c = Factory.GetCharacter();
c.Name = "B";
c.FirstName = "测试2";
c.NickName = "B";
c.MagicType = MagicType.Fleabane;
c.InitialHP = 355;
c.InitialSTR = 5;
c.InitialAGI = 5;
c.InitialINT = 25;
c.InitialATK = 75;
c.InitialDEF = 20;
c.InitialSPD = 320;
config.Add("B", c);
c = Factory.GetCharacter();
c.Name = "C";
c.FirstName = "测试3";
c.NickName = "B的复制人";
c.MagicType = MagicType.Fleabane;
c.InitialHP = 355;
c.InitialSTR = 5;
c.InitialAGI = 5;
c.InitialINT = 25;
c.InitialATK = 75;
c.InitialDEF = 20;
c.InitialSPD = 320;
config.Add("C", c);
config.SaveConfig(); config.SaveConfig();
PluginConfig config2 = new(Name, "config") PluginConfig config2 = new(Name, "config")
{ {