From 6fe9e9ab59b048253a8b1ca952304f5fe28162a9 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Tue, 28 Nov 2023 19:32:19 +0900 Subject: [PATCH 01/11] make BattleStatus.Tick and Buff.Stun --- Lib9c/Model/BattleStatus/Tick.cs | 28 ++++++++++++++++++++++++++++ Lib9c/Model/Buff/Stun.cs | 22 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 Lib9c/Model/BattleStatus/Tick.cs create mode 100644 Lib9c/Model/Buff/Stun.cs diff --git a/Lib9c/Model/BattleStatus/Tick.cs b/Lib9c/Model/BattleStatus/Tick.cs new file mode 100644 index 0000000000..505b7e59b2 --- /dev/null +++ b/Lib9c/Model/BattleStatus/Tick.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Nekoyume.Model.BattleStatus +{ + [Serializable] + public class Tick : Skill + { + public Tick(CharacterBase character) : this( + 0, + character, + ArraySegment.Empty, + ArraySegment.Empty) + { + } + + public Tick(int skillId, CharacterBase character, IEnumerable skillInfos, IEnumerable buffInfos) + : base(skillId, character, skillInfos, buffInfos) + { + } + + public override IEnumerator CoExecute(IStage stage) + { + yield return null; + } + } +} diff --git a/Lib9c/Model/Buff/Stun.cs b/Lib9c/Model/Buff/Stun.cs new file mode 100644 index 0000000000..3ba5062ef1 --- /dev/null +++ b/Lib9c/Model/Buff/Stun.cs @@ -0,0 +1,22 @@ +using System; + +namespace Nekoyume.Model.Buff +{ + [Serializable] + public class Stun : Buff + { + public Stun(BuffInfo buffInfo) : base(buffInfo) + { + + } + + protected Stun(Buff value) : base(value) + { + } + + public override object Clone() + { + return new Stun(this); + } + } +} From d1f84a0bdca81b46c6fadf2d07f73e84d6830fd1 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Tue, 28 Nov 2023 19:32:36 +0900 Subject: [PATCH 02/11] add usage of Tick and Stun to CharacterBase --- Lib9c/Model/Character/CharacterBase.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Lib9c/Model/Character/CharacterBase.cs b/Lib9c/Model/Character/CharacterBase.cs index 56902dd15f..7cd4295627 100644 --- a/Lib9c/Model/Character/CharacterBase.cs +++ b/Lib9c/Model/Character/CharacterBase.cs @@ -369,6 +369,11 @@ public void AddBuff(Buff.Buff buff, bool updateImmediate = true) var clone = (ActionBuff)action.Clone(); Buffs[action.RowData.GroupId] = clone; } + else if (buff is Stun stun) + { + var clone = (Stun)stun.Clone(); + Buffs[stun.BuffInfo.GroupId] = clone; + } } public void RemoveRecentStatBuff() @@ -509,8 +514,17 @@ private void Act() { ReduceDurationOfBuffs(); ReduceSkillCooldown(); - OnPreSkill(); - var usedSkill = UseSkill(); + BattleStatus.Skill usedSkill; + if (OnPreSkill()) + { + usedSkill = new Tick(this); + Simulator.Log.Add(usedSkill); + } + else + { + usedSkill = UseSkill(); + } + if (usedSkill != null) { OnPostSkill(usedSkill); @@ -556,9 +570,9 @@ private void ActV2() EndTurn(); } - protected virtual void OnPreSkill() + protected virtual bool OnPreSkill() { - + return Buffs.Values.Any(buff => buff is Stun); } protected virtual void OnPostSkill(BattleStatus.Skill usedSkill) From 5d8008a17520a6fdb4e40d71bd7cfd472c8d19f5 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Tue, 28 Nov 2023 19:32:49 +0900 Subject: [PATCH 03/11] add unit test about Stun buff --- .Lib9c.Tests/Model/PlayerTest.cs | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/.Lib9c.Tests/Model/PlayerTest.cs b/.Lib9c.Tests/Model/PlayerTest.cs index 0972f670ba..5892d414a9 100644 --- a/.Lib9c.Tests/Model/PlayerTest.cs +++ b/.Lib9c.Tests/Model/PlayerTest.cs @@ -9,6 +9,7 @@ namespace Lib9c.Tests.Model using Nekoyume.Battle; using Nekoyume.Model; using Nekoyume.Model.BattleStatus; + using Nekoyume.Model.Buff; using Nekoyume.Model.Item; using Nekoyume.Model.Quest; using Nekoyume.Model.Skill; @@ -422,5 +423,78 @@ public void MaxLevelTest() Assert.Equal(maxLevel, player.Level); Assert.Equal(requiredExp - 1, player.Exp.Current - expRow.Exp); } + + [Fact] + public void GetStun() + { + var defaultAttack = SkillFactory.GetV1( + _tableSheets.SkillSheet.Values.First(r => r.Id == GameConfig.DefaultAttackId), + 100, + 100 + ); + + var simulator = new StageSimulator( + _random, + _avatarState, + new List(), + null, + new List(), + 1, + 1, + _tableSheets.StageSheet[1], + _tableSheets.StageWaveSheet[1], + false, + 20, + _tableSheets.GetSimulatorSheets(), + _tableSheets.EnemySkillSheet, + _tableSheets.CostumeStatSheet, + StageSimulator.GetWaveRewards( + _random, + _tableSheets.StageSheet[1], + _tableSheets.MaterialItemSheet) + ); + var player = simulator.Player; + var enemy = new Enemy(player, _tableSheets.CharacterSheet.Values.First(), 1); + player.Targets.Add(enemy); + simulator.Characters = new SimplePriorityQueue(); + simulator.Characters.Enqueue(enemy, 0); + player.InitAI(); + player.OverrideSkill(defaultAttack); + + // force add buff 'Stun' + player.AddBuff(new Stun(new BuffInfo(1, 1, 100, 2, SkillTargetType.Self))); + var actionBuffSheet = _tableSheets.ActionBuffSheet; + var row = actionBuffSheet.Values.First(); + var bleed = BuffFactory.GetActionBuff(enemy.Stats, row); + player.AddBuff(bleed); + player.Tick(); + player.Tick(); + Assert.NotEmpty(simulator.Log); + var log = simulator.Log; + var logCount = log.Count; + var logList = log.ToList(); + for (int i = 0; i < logCount; i++) + { + var currLog = logList[i]; + if (currLog is Tick) + { + var nextLog = logList[i + 1]; + + // 'Tick' does not give damage + Assert.Equal(currLog.Character.Targets.First().CurrentHP, nextLog.Character.Targets.First().CurrentHP); + Assert.True(nextLog is TickDamage); + } + else if (currLog is TickDamage) + { + var nextLog = logList[i + 1]; + Assert.True(currLog.Character.CurrentHP > nextLog.Character.CurrentHP); + } + } + + Assert.True(logList.Count > 0); + Assert.Contains(logList, e => e is Tick); + Assert.Contains(logList, e => e is TickDamage); + Assert.Contains(logList, e => e is RemoveBuffs); + } } } From 7fc2efb9eb738c8254d8b564b7fd1cd6d90124d2 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Wed, 29 Nov 2023 16:33:53 +0900 Subject: [PATCH 04/11] fix CharacterBase.Act() for adding character.Clone to BattleStatus.Tick --- Lib9c/Model/Character/CharacterBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib9c/Model/Character/CharacterBase.cs b/Lib9c/Model/Character/CharacterBase.cs index 7cd4295627..27b9610de9 100644 --- a/Lib9c/Model/Character/CharacterBase.cs +++ b/Lib9c/Model/Character/CharacterBase.cs @@ -517,7 +517,7 @@ private void Act() BattleStatus.Skill usedSkill; if (OnPreSkill()) { - usedSkill = new Tick(this); + usedSkill = new Tick((CharacterBase)Clone()); Simulator.Log.Add(usedSkill); } else From f1acaa31ad4da4669dfd8c5255560875591d76a0 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Wed, 29 Nov 2023 16:34:08 +0900 Subject: [PATCH 05/11] change Stun to ActtionBuff --- Lib9c/Model/Buff/BuffFactory.cs | 4 ++++ Lib9c/Model/Buff/Stun.cs | 22 +++++++++++++++++++--- Lib9c/Model/Skill/ActionBuffType.cs | 1 + 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Lib9c/Model/Buff/BuffFactory.cs b/Lib9c/Model/Buff/BuffFactory.cs index 760b828e8f..eda605fb85 100644 --- a/Lib9c/Model/Buff/BuffFactory.cs +++ b/Lib9c/Model/Buff/BuffFactory.cs @@ -25,6 +25,8 @@ public static ActionBuff GetActionBuff(Stats stat, ActionBuffSheet.Row row) case ActionBuffType.Bleed: var power = (int)decimal.Round(stat.ATK * row.ATKPowerRatio); return new Bleed(row, power); + case ActionBuffType.Stun: + return new Stun(row); default: throw new ArgumentOutOfRangeException(); } @@ -36,6 +38,8 @@ public static ActionBuff GetCustomActionBuff(SkillCustomField customField, Actio { case ActionBuffType.Bleed: return new Bleed(customField, row); + case ActionBuffType.Stun: + return new Stun(customField, row); default: throw new ArgumentOutOfRangeException(); } diff --git a/Lib9c/Model/Buff/Stun.cs b/Lib9c/Model/Buff/Stun.cs index 3ba5062ef1..bd0d93a60b 100644 --- a/Lib9c/Model/Buff/Stun.cs +++ b/Lib9c/Model/Buff/Stun.cs @@ -1,16 +1,22 @@ using System; +using Nekoyume.Model.BattleStatus.Arena; +using Nekoyume.Model.Skill; +using Nekoyume.TableData; namespace Nekoyume.Model.Buff { [Serializable] - public class Stun : Buff + public class Stun : ActionBuff { - public Stun(BuffInfo buffInfo) : base(buffInfo) + public Stun(ActionBuffSheet.Row row) : base(row) { + } + public Stun(SkillCustomField customField, ActionBuffSheet.Row row) : base(customField, row) + { } - protected Stun(Buff value) : base(value) + protected Stun(ActionBuff value) : base(value) { } @@ -18,5 +24,15 @@ public override object Clone() { return new Stun(this); } + + public override BattleStatus.Skill GiveEffect(CharacterBase affectedCharacter, int simulatorWaveTurn, bool copyCharacter = true) + { + throw new NotImplementedException(); + } + + public override ArenaSkill GiveEffectForArena(ArenaCharacter affectedCharacter, int simulatorWaveTurn) + { + throw new NotImplementedException(); + } } } diff --git a/Lib9c/Model/Skill/ActionBuffType.cs b/Lib9c/Model/Skill/ActionBuffType.cs index 40c5e190e7..652df29129 100644 --- a/Lib9c/Model/Skill/ActionBuffType.cs +++ b/Lib9c/Model/Skill/ActionBuffType.cs @@ -4,5 +4,6 @@ namespace Nekoyume.Model.Skill public enum ActionBuffType { Bleed, + Stun, } } From f2dcc3f031882c938fdbe28067d3d7b0a24562ae Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Wed, 29 Nov 2023 16:35:10 +0900 Subject: [PATCH 06/11] add temporary skill and action buff about Stun skill id: 700004, action buff id: 704000 --- Lib9c/TableCSV/Skill/ActionBuffSheet.csv | 3 ++- Lib9c/TableCSV/Skill/SkillActionBuffSheet.csv | 3 ++- Lib9c/TableCSV/Skill/SkillSheet.csv | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Lib9c/TableCSV/Skill/ActionBuffSheet.csv b/Lib9c/TableCSV/Skill/ActionBuffSheet.csv index 014a9d3c22..8111723706 100644 --- a/Lib9c/TableCSV/Skill/ActionBuffSheet.csv +++ b/Lib9c/TableCSV/Skill/ActionBuffSheet.csv @@ -2,4 +2,5 @@ id,group,_name,chance,duration,target_type,buff_type,elemental_type,atk_power_ra 500001,500001,출혈(0.5),100,10,Enemy,Bleed,Normal,0.5 500002,500001,출혈(0.4),100,10,Enemy,Bleed,Normal,0.4 500003,500001,출혈(0.2),100,10,Enemy,Bleed,Normal,0.2 -600001,600001,출혈,100,0,Enemies,Bleed,Normal,1 \ No newline at end of file +600001,600001,출혈,100,0,Enemies,Bleed,Normal,1 +704000,704000,기절,100,0,Enemy,Stun,Normal,0 diff --git a/Lib9c/TableCSV/Skill/SkillActionBuffSheet.csv b/Lib9c/TableCSV/Skill/SkillActionBuffSheet.csv index 1f99b57563..d462e5b892 100644 --- a/Lib9c/TableCSV/Skill/SkillActionBuffSheet.csv +++ b/Lib9c/TableCSV/Skill/SkillActionBuffSheet.csv @@ -2,4 +2,5 @@ skill_id,buff_id 500003,500001 500004,500002 500005,500003 -600001,600001 \ No newline at end of file +600001,600001 +700004,704000 diff --git a/Lib9c/TableCSV/Skill/SkillSheet.csv b/Lib9c/TableCSV/Skill/SkillSheet.csv index 3e6b9a0748..a9ed44380a 100644 --- a/Lib9c/TableCSV/Skill/SkillSheet.csv +++ b/Lib9c/TableCSV/Skill/SkillSheet.csv @@ -166,4 +166,5 @@ _250001,속도 증가(전체),Normal,Buff,SpeedBuff,Ally,1,1 // 미구현 600001,출혈,Normal,Debuff,Buff,Enemy,1,15 700001,피해 감소 (고정),Normal,Buff,DamageReductionBuff,Self,1,15 700002,피해 감소 (비율),Normal,Buff,DamageReductionBuff,Self,1,15 -700003,치명 데미지 증가,Normal,Buff,CriticalDamageBuff,Self,1,15 \ No newline at end of file +700003,치명 데미지 증가,Normal,Buff,CriticalDamageBuff,Self,1,15 +700004,기절,Normal,Debuff,Buff,Enemy,1,15 From fa312a8b39bac1fa4464c61749d3e96b7a98c991 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Wed, 29 Nov 2023 16:56:55 +0900 Subject: [PATCH 07/11] add unit test about Stun skill --- .Lib9c.Tests/Model/PlayerTest.cs | 78 +++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/.Lib9c.Tests/Model/PlayerTest.cs b/.Lib9c.Tests/Model/PlayerTest.cs index 5892d414a9..4d6098b05d 100644 --- a/.Lib9c.Tests/Model/PlayerTest.cs +++ b/.Lib9c.Tests/Model/PlayerTest.cs @@ -461,9 +461,10 @@ public void GetStun() player.InitAI(); player.OverrideSkill(defaultAttack); - // force add buff 'Stun' - player.AddBuff(new Stun(new BuffInfo(1, 1, 100, 2, SkillTargetType.Self))); var actionBuffSheet = _tableSheets.ActionBuffSheet; + // force add buff 'Stun' + // 704000 is ActionBuff id of Stun + player.AddBuff(BuffFactory.GetActionBuff(player.Stats, actionBuffSheet[704000])); var row = actionBuffSheet.Values.First(); var bleed = BuffFactory.GetActionBuff(enemy.Stats, row); player.AddBuff(bleed); @@ -496,5 +497,78 @@ public void GetStun() Assert.Contains(logList, e => e is TickDamage); Assert.Contains(logList, e => e is RemoveBuffs); } + + [Fact] + public void GiveStun() + { + var simulator = new StageSimulator( + _random, + _avatarState, + new List(), + null, + new List(), + 1, + 1, + _tableSheets.StageSheet[1], + _tableSheets.StageWaveSheet[1], + false, + 20, + _tableSheets.GetSimulatorSheets(), + _tableSheets.EnemySkillSheet, + _tableSheets.CostumeStatSheet, + StageSimulator.GetWaveRewards( + _random, + _tableSheets.StageSheet[1], + _tableSheets.MaterialItemSheet) + ); + var skill = SkillFactory.Get(_tableSheets.SkillSheet[700004], 0, 100, 0, StatType.NONE); + skill.CustomField = new SkillCustomField { BuffDuration = 2 }; + var player = simulator.Player; + var enemy = new Enemy(player, _tableSheets.CharacterSheet.Values.First(), 1); + player.Targets.Add(enemy); + simulator.Characters = new SimplePriorityQueue(); + simulator.Characters.Enqueue(enemy, 0); + player.InitAI(); + enemy.InitAI(); + player.AddSkill(skill); + player.Tick(); + var actionBuffSheet = _tableSheets.ActionBuffSheet; + var row = actionBuffSheet.Values.First(); + var bleed = BuffFactory.GetActionBuff(enemy.Stats, row); + enemy.AddBuff(bleed); + enemy.Tick(); + enemy.Tick(); + enemy.Tick(); + Assert.NotEmpty(simulator.Log); + var log = simulator.Log; + var logCount = log.Count; + var logList = log.ToList(); + for (int i = 0; i < logCount; i++) + { + var currLog = logList[i]; + if (currLog is Tick) + { + var nextLog = logList[i + 1]; + + // 'Tick' does not give damage + Assert.Equal(currLog.Character.Targets.First().CurrentHP, nextLog.Character.Targets.First().CurrentHP); + Assert.True(nextLog is TickDamage); + } + else if (currLog is TickDamage) + { + var nextLog = logList.ElementAtOrDefault(i + 1); + if (nextLog != null) + { + Assert.True(currLog.Character.CurrentHP > nextLog.Character.CurrentHP); + } + } + } + + Assert.True(logList.Count > 0); + Assert.Contains(logList, e => e is Tick); + Assert.Contains(logList, e => e is TickDamage); + Assert.Contains(logList, e => e is RemoveBuffs); + Assert.Contains(logList, e => e is Nekoyume.Model.BattleStatus.NormalAttack); + } } } From 7d3b796a20a9fabd2e9bb227cc73a8054fe255a5 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Thu, 30 Nov 2023 15:03:44 +0900 Subject: [PATCH 08/11] add ArenaTick --- Lib9c/Model/BattleStatus/Arena/ArenaTick.cs | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Lib9c/Model/BattleStatus/Arena/ArenaTick.cs diff --git a/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs b/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs new file mode 100644 index 0000000000..fa84017b5d --- /dev/null +++ b/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Nekoyume.Model.BattleStatus.Arena +{ + [Serializable] + public class ArenaTick : ArenaSkill + { + public ArenaTick(ArenaCharacter character) : this( + character, + ArraySegment.Empty, + ArraySegment.Empty) + { + } + + public ArenaTick(ArenaCharacter character, IEnumerable skillInfos, IEnumerable buffInfos) + : base(character, skillInfos, buffInfos) + { + } + + public override IEnumerator CoExecute(IArena arena) + { + yield return null; + } + } +} From d4f74f243b4f0303708fd15873a2295dd595d0f0 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Thu, 30 Nov 2023 15:04:06 +0900 Subject: [PATCH 09/11] fix ArenaCharacter.Act and OnPreSkill for reflect Stun --- Lib9c/Model/Character/ArenaCharacter.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Lib9c/Model/Character/ArenaCharacter.cs b/Lib9c/Model/Character/ArenaCharacter.cs index 53ab676d17..0d268c8eee 100644 --- a/Lib9c/Model/Character/ArenaCharacter.cs +++ b/Lib9c/Model/Character/ArenaCharacter.cs @@ -566,8 +566,17 @@ private void Act() ReduceDurationOfBuffs(); ReduceSkillCooldown(); - OnPreSkill(); - var usedSkill = UseSkill(); + ArenaSkill usedSkill; + if (OnPreSkill()) + { + usedSkill = new ArenaTick((ArenaCharacter)Clone()); + _simulator.Log.Add(usedSkill); + } + else + { + usedSkill = UseSkill(); + } + if (usedSkill != null) { OnPostSkill(usedSkill); @@ -603,9 +612,9 @@ private void ActV2() RemoveBuffs(); } - protected virtual void OnPreSkill() + protected virtual bool OnPreSkill() { - + return Buffs.Values.Any(buff => buff is Stun); } protected virtual void OnPostSkill(BattleStatus.Arena.ArenaSkill usedSkill) From 046643e03cd00b831cca52c62db608e51f1f4942 Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Thu, 30 Nov 2023 17:09:29 +0900 Subject: [PATCH 10/11] change Stun.GiveEffect and GiveEffectForArena remove throw exception, return null. not using code --- Lib9c/Model/Buff/Stun.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib9c/Model/Buff/Stun.cs b/Lib9c/Model/Buff/Stun.cs index bd0d93a60b..8431df1c3d 100644 --- a/Lib9c/Model/Buff/Stun.cs +++ b/Lib9c/Model/Buff/Stun.cs @@ -27,12 +27,14 @@ public override object Clone() public override BattleStatus.Skill GiveEffect(CharacterBase affectedCharacter, int simulatorWaveTurn, bool copyCharacter = true) { - throw new NotImplementedException(); + // Do not anything + return null; } public override ArenaSkill GiveEffectForArena(ArenaCharacter affectedCharacter, int simulatorWaveTurn) { - throw new NotImplementedException(); + // Do not anything + return null; } } } From 0d5c718c61a851f5782a512079cf77574b257a8f Mon Sep 17 00:00:00 2001 From: sonohoshi Date: Thu, 30 Nov 2023 17:27:05 +0900 Subject: [PATCH 11/11] change Tick.CoExecute to return CoTickDamage --- Lib9c/Model/BattleStatus/Arena/ArenaTick.cs | 2 +- Lib9c/Model/BattleStatus/Tick.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs b/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs index fa84017b5d..56287ab473 100644 --- a/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs +++ b/Lib9c/Model/BattleStatus/Arena/ArenaTick.cs @@ -21,7 +21,7 @@ public ArenaTick(ArenaCharacter character, IEnumerable skillInfo public override IEnumerator CoExecute(IArena arena) { - yield return null; + yield return arena.CoTickDamage(Character, SkillInfos); } } } diff --git a/Lib9c/Model/BattleStatus/Tick.cs b/Lib9c/Model/BattleStatus/Tick.cs index 505b7e59b2..a0d6330032 100644 --- a/Lib9c/Model/BattleStatus/Tick.cs +++ b/Lib9c/Model/BattleStatus/Tick.cs @@ -22,7 +22,7 @@ public Tick(int skillId, CharacterBase character, IEnumerable skillIn public override IEnumerator CoExecute(IStage stage) { - yield return null; + yield return stage.CoTickDamage(Character, SkillId, SkillInfos); } } }