From 4bca541f48e17ec5728c0f37071140677ddb385b Mon Sep 17 00:00:00 2001 From: Yang Chun Ung Date: Thu, 29 Feb 2024 01:08:36 +0900 Subject: [PATCH] Divide SetRuneStats, RuneSkills for fix rune skill --- .Lib9c.Tests/Model/ArenaSimulatorTest.cs | 67 ++++++++++++++++++++++++ .Lib9c.Tests/Model/PlayerTest.cs | 4 +- Lib9c/Arena/ArenaSimulatorV4.cs | 12 ++--- Lib9c/Battle/RaidSimulator.cs | 10 +++- Lib9c/Battle/StageSimulator.cs | 10 +++- Lib9c/Model/Character/ArenaCharacter.cs | 37 +++++++++---- Lib9c/Model/Character/Player.cs | 32 +++++++++-- 7 files changed, 145 insertions(+), 27 deletions(-) diff --git a/.Lib9c.Tests/Model/ArenaSimulatorTest.cs b/.Lib9c.Tests/Model/ArenaSimulatorTest.cs index a321e23c24..5bb6bfd4ac 100644 --- a/.Lib9c.Tests/Model/ArenaSimulatorTest.cs +++ b/.Lib9c.Tests/Model/ArenaSimulatorTest.cs @@ -282,5 +282,72 @@ public void Thorns() Assert.True(challengerTick.Character.HP > enemyTick.Character.HP); Assert.True(enemyTick.SkillInfos.First().Effect > challengerTick.SkillInfos.First().Effect); } + + [Fact] + public void Bleed() + { + var random = new TestRandom(); + var avatarState1 = _avatarState1; + var avatarState2 = _avatarState2; + + var arenaAvatarState1 = new ArenaAvatarState(avatarState1); + var arenaAvatarState2 = new ArenaAvatarState(avatarState2); + + var characterRow = _tableSheets.CharacterSheet[GameConfig.DefaultAvatarCharacterId]; + var stats = characterRow.ToStats(avatarState1.level); + var totalAtk = 141138; + var baseAtk = stats.ATK; + var runeOptionSheet = _tableSheets.RuneOptionSheet; + var runeRow = runeOptionSheet[10003]; + var rune = new RuneState(10003); + while (rune.Level < 89) + { + rune.LevelUp(); + } + + var optionInfo = runeRow.LevelOptionMap[89]; + var statModifiers = new List(); + statModifiers.AddRange( + optionInfo.Stats.Select(x => + new StatModifier( + x.stat.StatType, + x.operationType, + x.stat.TotalValueAsLong))); + foreach (var modifier in statModifiers) + { + if (modifier.StatType == StatType.ATK) + { + baseAtk += modifier.Value; + } + } + + // Add collection modifier without level stats, rune stats + var collectionModifier = new StatModifier(StatType.ATK, StatModifier.OperationType.Add, totalAtk - baseAtk); + var modifiers = new List + { + collectionModifier, + new (StatType.HP, StatModifier.OperationType.Add, totalAtk * 10), + }; + + var simulator = new ArenaSimulator(random); + var myDigest = new ArenaPlayerDigest(avatarState1, arenaAvatarState1); + myDigest.Runes.Add(rune); + var enemyDigest = new ArenaPlayerDigest(avatarState2, arenaAvatarState2); + enemyDigest.Runes.Add(rune); + var arenaSheets = _tableSheets.GetArenaSimulatorSheets(); + var log = simulator.Simulate(myDigest, enemyDigest, arenaSheets, modifiers, modifiers, true); + var spawns = log.Events.OfType().ToList(); + Assert.All(spawns, spawn => Assert.Equal(totalAtk, spawn.Character.ATK)); + var ticks = log.Events + .OfType() + .ToList(); + var challengerTick = ticks.First(r => !r.Character.IsEnemy); + var enemyTick = ticks.First(r => r.Character.IsEnemy); + var challengerInfo = challengerTick.SkillInfos.First(); + var enemyInfo = enemyTick.SkillInfos.First(); + var dmg = (int)decimal.Round(totalAtk * optionInfo.SkillValue); + Assert.Equal(dmg, challengerInfo.Effect); + Assert.Equal(dmg, enemyInfo.Effect); + } } } diff --git a/.Lib9c.Tests/Model/PlayerTest.cs b/.Lib9c.Tests/Model/PlayerTest.cs index f86ab59a3d..e920816712 100644 --- a/.Lib9c.Tests/Model/PlayerTest.cs +++ b/.Lib9c.Tests/Model/PlayerTest.cs @@ -727,7 +727,7 @@ public void StatsLayerTest() { runeState, }; - player.SetRune(runeStates, _tableSheets.RuneOptionSheet, _tableSheets.SkillSheet); + player.SetRuneStats(runeStates, _tableSheets.RuneOptionSheet); var runeOptionRow = _tableSheets.RuneOptionSheet.Values.First(r => r.RuneId == runeId); var runeAtk = runeOptionRow.LevelOptionMap[1].Stats.Sum(r => r.stat.BaseValueAsLong); Assert.Equal(player.ATK, consumableLayerAtk + runeAtk); @@ -866,7 +866,7 @@ public void IncreaseHpForArena() { runeState, }; - player.SetRune(runeStates, _tableSheets.RuneOptionSheet, _tableSheets.SkillSheet); + player.SetRuneStats(runeStates, _tableSheets.RuneOptionSheet); var runeOptionRow = _tableSheets.RuneOptionSheet.Values.First(r => r.RuneId == runeId); var runeHp = runeOptionRow.LevelOptionMap[1].Stats.Sum(r => r.stat.BaseValueAsLong); Assert.Equal(consumableLayerHp + runeHp, player.HP); diff --git a/Lib9c/Arena/ArenaSimulatorV4.cs b/Lib9c/Arena/ArenaSimulatorV4.cs index cd543d0f95..01db3b1d03 100644 --- a/Lib9c/Arena/ArenaSimulatorV4.cs +++ b/Lib9c/Arena/ArenaSimulatorV4.cs @@ -105,19 +105,15 @@ private static SimplePriorityQueue SpawnPlayers( var challenger = new ArenaCharacter(simulator, challengerDigest, simulatorSheets); if (challengerDigest.Runes != null) { - challenger.SetRune( - challengerDigest.Runes, - simulatorSheets.RuneOptionSheet, - simulatorSheets.SkillSheet); + challenger.SetRuneStats(challengerDigest.Runes, simulatorSheets.RuneOptionSheet); + challenger.SetRuneSkills(challengerDigest.Runes, simulatorSheets.RuneOptionSheet, simulatorSheets.SkillSheet); } var enemy = new ArenaCharacter(simulator, enemyDigest, simulatorSheets, true); if (enemyDigest.Runes != null) { - enemy.SetRune( - enemyDigest.Runes, - simulatorSheets.RuneOptionSheet, - simulatorSheets.SkillSheet); + enemy.SetRuneStats(enemyDigest.Runes, simulatorSheets.RuneOptionSheet); + enemy.SetRuneSkills(enemyDigest.Runes, simulatorSheets.RuneOptionSheet, simulatorSheets.SkillSheet); } challenger.Spawn(enemy); diff --git a/Lib9c/Battle/RaidSimulator.cs b/Lib9c/Battle/RaidSimulator.cs index c58dc530b1..bb4b27137c 100644 --- a/Lib9c/Battle/RaidSimulator.cs +++ b/Lib9c/Battle/RaidSimulator.cs @@ -38,7 +38,15 @@ public RaidSimulator( CostumeStatSheet costumeStatSheet, List collectionModifiers) : base(random, avatarState, foods, simulatorSheets) { - Player.ConfigureStats(costumeStatSheet, runeStates, simulatorSheets.RuneOptionSheet, simulatorSheets.SkillSheet, collectionModifiers); + var runeOptionSheet = simulatorSheets.RuneOptionSheet; + var skillSheet = simulatorSheets.SkillSheet; + Player.ConfigureStats(costumeStatSheet, runeStates, runeOptionSheet, skillSheet, + collectionModifiers); + if (runeStates is not null) + { + // call SetRuneSkills last. because rune skills affect from total calculated stats + Player.SetRuneSkills(runeStates, runeOptionSheet, skillSheet); + } BossId = bossId; _waves = new List(); diff --git a/Lib9c/Battle/StageSimulator.cs b/Lib9c/Battle/StageSimulator.cs index a84c675d74..6222cf839e 100644 --- a/Lib9c/Battle/StageSimulator.cs +++ b/Lib9c/Battle/StageSimulator.cs @@ -57,7 +57,15 @@ public StageSimulator(IRandom random, simulatorSheets, logEvent) { - Player.ConfigureStats(costumeStatSheet, runeStates, simulatorSheets.RuneOptionSheet, simulatorSheets.SkillSheet, collectionModifiers); + var runeOptionSheet = simulatorSheets.RuneOptionSheet; + var skillSheet = simulatorSheets.SkillSheet; + Player.ConfigureStats(costumeStatSheet, runeStates, runeOptionSheet, skillSheet, + collectionModifiers); + if (runeStates is not null) + { + // call SetRuneSkills last. because rune skills affect from total calculated stats + Player.SetRuneSkills(runeStates, runeOptionSheet, skillSheet); + } _waves = new List(); _waveRewards = waveRewards; diff --git a/Lib9c/Model/Character/ArenaCharacter.cs b/Lib9c/Model/Character/ArenaCharacter.cs index cf7233da9e..e695f32726 100644 --- a/Lib9c/Model/Character/ArenaCharacter.cs +++ b/Lib9c/Model/Character/ArenaCharacter.cs @@ -186,16 +186,21 @@ public ArenaCharacter( hpModifier); _skills = GetSkills(digest.Equipments, sheets.SkillSheet); _attackCountMax = AttackCountHelper.GetCountMax(digest.Level); - if (digest.Runes != null) + + var runes = digest.Runes; + var runeOptionSheet = sheets.RuneOptionSheet; + bool runeExist = runes != null; + if (runeExist) { - SetRune( - digest.Runes, - sheets.RuneOptionSheet, - sheets.SkillSheet); + SetRuneStats(runes, runeOptionSheet); } - Stats.SetCollections(collectionModifiers); ResetCurrentHP(); + if (runeExist) + { + // call SetRuneSkills last. because rune skills affect from total calculated stats + SetRuneSkills(runes, runeOptionSheet, sheets.SkillSheet); + } } private ArenaCharacter(ArenaCharacter value) @@ -443,10 +448,7 @@ public void SetRuneV2( } } - public void SetRune( - List runes, - RuneOptionSheet runeOptionSheet, - SkillSheet skillSheet) + public void SetRuneStats(List runes, RuneOptionSheet runeOptionSheet) { foreach (var rune in runes) { @@ -465,6 +467,21 @@ public void SetRune( x.stat.TotalValueAsLong))); Stats.AddRune(statModifiers); ResetCurrentHP(); + } + } + + public void SetRuneSkills( + List runes, + RuneOptionSheet runeOptionSheet, + SkillSheet skillSheet) + { + foreach (var rune in runes) + { + if (!runeOptionSheet.TryGetValue(rune.RuneId, out var optionRow) || + !optionRow.LevelOptionMap.TryGetValue(rune.Level, out var optionInfo)) + { + continue; + } if (optionInfo.SkillId == default || !skillSheet.TryGetValue(optionInfo.SkillId, out var skillRow)) diff --git a/Lib9c/Model/Character/Player.cs b/Lib9c/Model/Character/Player.cs index e309bba5b5..b312db53c8 100644 --- a/Lib9c/Model/Character/Player.cs +++ b/Lib9c/Model/Character/Player.cs @@ -559,10 +559,12 @@ public void SetCostumeStat(CostumeStatSheet costumeStatSheet) ResetCurrentHP(); } - public void SetRune( - List runes, - RuneOptionSheet runeOptionSheet, - SkillSheet skillSheet) + /// + /// Sets the rune stats for a player character. + /// + /// The list of rune states for the player character. + /// The rune option sheet that contains information about rune options. + public void SetRuneStats(List runes, RuneOptionSheet runeOptionSheet) { foreach (var rune in runes) { @@ -573,6 +575,26 @@ public void SetRune( Stats.AddRuneStat(optionInfo); ResetCurrentHP(); + } + } + + /// + /// Sets the rune skills for the player. + /// + /// The list of rune states. + /// The rune option sheet. + /// The skill sheet. + public void SetRuneSkills( + List runes, + RuneOptionSheet runeOptionSheet, + SkillSheet skillSheet) + { + foreach (var rune in runes) + { + if (!runeOptionSheet.TryGetOptionInfo(rune.RuneId, rune.Level, out var optionInfo)) + { + continue; + } if (optionInfo.SkillId == default || !skillSheet.TryGetValue(optionInfo.SkillId, out var skillRow)) @@ -615,7 +637,7 @@ public void ConfigureStats(CostumeStatSheet costumeStatSheet, List ru SetCostumeStat(costumeStatSheet); if (runeStates != null) { - SetRune(runeStates, runeOptionSheet, skillSheet); + SetRuneStats(runeStates, runeOptionSheet); } SetCollections(collectionModifiers);