From 1e4589fcda3372aa5c26692ed2e6c984fa072a20 Mon Sep 17 00:00:00 2001 From: "Sam Smith (Microsoft)" Date: Tue, 25 May 2021 15:57:00 -0400 Subject: [PATCH 1/2] Resolved radius/range inconsistencies --- src/Battle.Logic/Map/FieldOfView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Battle.Logic/Map/FieldOfView.cs b/src/Battle.Logic/Map/FieldOfView.cs index 7de4a7f8..0e67b7c6 100644 --- a/src/Battle.Logic/Map/FieldOfView.cs +++ b/src/Battle.Logic/Map/FieldOfView.cs @@ -12,10 +12,10 @@ public static List GetFieldOfView(string[,] map, Vector3 location, int return MapCore.GetMapArea(map, location, range, true); } - public static List GetCharactersInArea(List characters, string[,] map, Vector3 location, int radius) + public static List GetCharactersInArea(List characters, string[,] map, Vector3 location, int range) { List results = new(); - List area = MapCore.GetMapArea(map, location, radius, false, true); + List area = MapCore.GetMapArea(map, location, range, false, true); foreach (Character character in characters) { foreach (Vector3 item in area) From fe03249fa660c803de0f596ea4fe8e4f27d37f15 Mon Sep 17 00:00:00 2001 From: "Sam Smith (Microsoft)" Date: Tue, 25 May 2021 18:44:33 -0400 Subject: [PATCH 2/2] Added reload --- src/Battle.Logic/Characters/Character.cs | 1 + src/Battle.Logic/Encounters/Encounter.cs | 71 +++++++++++-------- src/Battle.Logic/Items/Weapon.cs | 5 ++ .../Encounters/RegularAttackTests.cs | 57 +++++++++++++++ 4 files changed, 104 insertions(+), 30 deletions(-) diff --git a/src/Battle.Logic/Characters/Character.cs b/src/Battle.Logic/Characters/Character.cs index 3ab8b439..47b5081b 100644 --- a/src/Battle.Logic/Characters/Character.cs +++ b/src/Battle.Logic/Characters/Character.cs @@ -157,5 +157,6 @@ private static bool LocationIsAdjacentToList(Vector3 location, List lis } return false; } + } } diff --git a/src/Battle.Logic/Encounters/Encounter.cs b/src/Battle.Logic/Encounters/Encounter.cs index 8fc7fea3..21972da2 100644 --- a/src/Battle.Logic/Encounters/Encounter.cs +++ b/src/Battle.Logic/Encounters/Encounter.cs @@ -77,48 +77,59 @@ public static EncounterResult AttackCharacterWithAreaOfEffect(Character sourceCh public static EncounterResult AttackCharacter(Character sourceCharacter, Weapon weapon, Character targetCharacter, string[,] map, Queue diceRolls) { - int damageDealt = 0; - bool isCriticalHit = false; - List log = new(); - log.Add(sourceCharacter.Name + " is attacking with " + weapon.Name + ", targeted on " + targetCharacter.Name.ToString()); - if (diceRolls == null || diceRolls.Count == 0) { return null; } - int toHitPercent = EncounterCore.GetChanceToHit(sourceCharacter, weapon, targetCharacter); - //If the number rolled is higher than the chance to hit, the attack was successful! - int randomToHit = diceRolls.Dequeue(); + int damageDealt = 0; + bool isCriticalHit = false; + List log = new(); + log.Add(sourceCharacter.Name + " is attacking with " + weapon.Name + ", targeted on " + targetCharacter.Name.ToString()); - if ((100 - toHitPercent) <= randomToHit) + //Don't attack if the clip is empty + if (weapon.ClipRemaining > 0) { - log.Add("Hit: Chance to hit: " + toHitPercent.ToString() + ", (dice roll: " + randomToHit.ToString() + ")"); + int toHitPercent = EncounterCore.GetChanceToHit(sourceCharacter, weapon, targetCharacter); - EncounterResult tempResult = ProcessCharacterDamageAndExperience(sourceCharacter, weapon, targetCharacter, map, diceRolls, log, false); - sourceCharacter = tempResult.SourceCharacter; - targetCharacter = tempResult.TargetCharacter; - damageDealt = tempResult.DamageDealt; - isCriticalHit = tempResult.IsCriticalHit; - log = tempResult.Log; - } - else - { - log.Add("Missed: Chance to hit: " + toHitPercent.ToString() + ", (dice roll: " + randomToHit.ToString() + ")"); + //If the number rolled is higher than the chance to hit, the attack was successful! + int randomToHit = diceRolls.Dequeue(); - int xp = Experience.GetExperience(false); - sourceCharacter.Experience += xp; - log.Add(xp.ToString() + " XP added to character " + sourceCharacter.Name + ", for a total of " + sourceCharacter.Experience + " XP"); - } + if ((100 - toHitPercent) <= randomToHit) + { + log.Add("Hit: Chance to hit: " + toHitPercent.ToString() + ", (dice roll: " + randomToHit.ToString() + ")"); + + EncounterResult tempResult = ProcessCharacterDamageAndExperience(sourceCharacter, weapon, targetCharacter, map, diceRolls, log, false); + sourceCharacter = tempResult.SourceCharacter; + targetCharacter = tempResult.TargetCharacter; + damageDealt = tempResult.DamageDealt; + isCriticalHit = tempResult.IsCriticalHit; + log = tempResult.Log; + } + else + { + log.Add("Missed: Chance to hit: " + toHitPercent.ToString() + ", (dice roll: " + randomToHit.ToString() + ")"); - //Consume source characters action points - sourceCharacter.ActionPoints = 0; + int xp = Experience.GetExperience(false); + sourceCharacter.Experience += xp; + log.Add(xp.ToString() + " XP added to character " + sourceCharacter.Name + ", for a total of " + sourceCharacter.Experience + " XP"); + } - //Check if the character has enough experience to level up - sourceCharacter.LevelUpIsReady = Experience.CheckIfReadyToLevelUp(sourceCharacter.Level, sourceCharacter.Experience); - if (sourceCharacter.LevelUpIsReady == true) + //Consume source characters action points + sourceCharacter.ActionPoints = 0; + //Consume weapon ammo + weapon.ClipRemaining--; + + //Check if the character has enough experience to level up + sourceCharacter.LevelUpIsReady = Experience.CheckIfReadyToLevelUp(sourceCharacter.Level, sourceCharacter.Experience); + if (sourceCharacter.LevelUpIsReady == true) + { + log.Add(sourceCharacter.Name + " is ready to level up"); + } + } + else { - log.Add(sourceCharacter.Name + " is ready to level up"); + log.Add(weapon.Name + " has no ammo remaining and the attack cannot be completed"); } EncounterResult result = new() diff --git a/src/Battle.Logic/Items/Weapon.cs b/src/Battle.Logic/Items/Weapon.cs index 65dd9933..8ad87d08 100644 --- a/src/Battle.Logic/Items/Weapon.cs +++ b/src/Battle.Logic/Items/Weapon.cs @@ -15,6 +15,11 @@ public class Weapon public int ClipRemaining { get; set; } public int ActionPointsRequired { get; set; } public WeaponType Type { get; set; } + + public void Reload() + { + ClipRemaining = ClipSize; + } } public enum WeaponType diff --git a/src/Battle.Tests/Encounters/RegularAttackTests.cs b/src/Battle.Tests/Encounters/RegularAttackTests.cs index f14ad524..a00c6cf9 100644 --- a/src/Battle.Tests/Encounters/RegularAttackTests.cs +++ b/src/Battle.Tests/Encounters/RegularAttackTests.cs @@ -743,5 +743,62 @@ public void FredAttacksWithRifleJeffBehindHalfCoverAndHunkeredDownInjuriesHimTes Assert.AreEqual(log, result.LogString); } + + [TestMethod] + public void FredAttacksJeffWithRifleWithNoAmmoTest() + { + //Arrange + Character fred = CharacterPool.CreateFredHero(); + Weapon rifle = fred.WeaponEquipped; + rifle.ClipRemaining = 0; + Character jeff = CharacterPool.CreateJeffBaddie(); + string[,] map = MapUtility.InitializeMap(10, 10); + Queue diceRolls = new(new List { 80, 100, 0 }); //Chance to hit roll, damage roll, critical chance roll + + //Act + EncounterResult result = Encounter.AttackCharacter(fred, rifle, jeff, map, diceRolls); + + //Assert + Assert.IsTrue(result != null); + //Assert.AreEqual(7, result.TargetCharacter.Hitpoints); + //Assert.AreEqual(10, result.SourceCharacter.Experience); + string log = @" +Fred is attacking with Rifle, targeted on Jeff +Rifle has no ammo remaining and the attack cannot be completed +"; + Assert.AreEqual(log, result.LogString); + } + + [TestMethod] + public void FredAttacksJeffWithRifleWithNoAmmoAndReloadsFirstTest() + { + //Arrange + Character fred = CharacterPool.CreateFredHero(); + Weapon rifle = fred.WeaponEquipped; + rifle.ClipRemaining = 0; + Character jeff = CharacterPool.CreateJeffBaddie(); + string[,] map = MapUtility.InitializeMap(10, 10); + Queue diceRolls = new(new List { 80, 100, 0 }); //Chance to hit roll, damage roll, critical chance roll + + //Act + fred.WeaponEquipped.Reload(); + EncounterResult result = Encounter.AttackCharacter(fred, rifle, jeff, map, diceRolls); + + //Assert + Assert.IsTrue(result != null); + Assert.AreEqual(7, result.TargetCharacter.Hitpoints); + Assert.AreEqual(10, result.SourceCharacter.Experience); + Assert.AreEqual(3, result.SourceCharacter.WeaponEquipped.ClipRemaining); + string log = @" +Fred is attacking with Rifle, targeted on Jeff +Hit: Chance to hit: 80, (dice roll: 80) +Damage range: 3-5, (dice roll: 100) +Critical chance: 70, (dice roll: 0) +5 damage dealt to character Jeff, HP is now 7 +10 XP added to character Fred, for a total of 10 XP +"; + Assert.AreEqual(log, result.LogString); + } + } } \ No newline at end of file