protected EnemyFighter(string name , int level , int health , int mana , int strength , int defense , int speed , int evade , int luck , IChanceService chanceService , List <Spell> spells = null , List <BattleMove> specialMoves = null) : base(name, level, health, mana, strength, defense, speed, evade, luck, spells, specialMoves) { ChanceService = chanceService; ExpGivenOnDefeat = 5 * level; _availableMoves = new List <BattleMove> { MoveFactory.Get(BattleMoveType.Attack) }; if (spells != null) { _availableMoves.AddRange(spells); } if (specialMoves != null) { _availableMoves.AddRange(specialMoves); } }
public override List <MenuAction> GetInteractableMenuActions(IInput input = null, IOutput output = null) { IMenu offerBloodTargetMenu = MenuFactory.GetMenu(MenuType.ChooseTargetMenu, input, output); IMenu offerBloodSubMenu = MenuFactory.GetMenu(MenuType.KeysOffOwnerNumberInputMenu, input, output, prompt: "how much HP shall you offer?", subMenu: offerBloodTargetMenu); IMenu praySubMenu = MenuFactory.GetMenu(MenuType.ChooseTargetMenu, input, output); string bellType = BellType.ToString().ToLower(); string bloodShortcut = $"blood {bellType}"; string prayShortcut = $"pray {bellType}"; return(new List <MenuAction> { new MenuAction($"offer blood to {DisplayName} ('{bloodShortcut}')", altText: bloodShortcut, move: MoveFactory.Get(BellMoveType.ControlMove), moveExecutor: this, subMenu: offerBloodSubMenu), new MenuAction($"pray to {DisplayName} ('{prayShortcut}')", altText: prayShortcut, move: MoveFactory.Get(BellMoveType.SealMove), moveExecutor: this, subMenu: praySubMenu) }); }
public void CastSpell_CorrectlyDoesNotReflectsSpells_ReflectStatus_DoesNotMatchAttackingType( [Values(MagicType.Fire, MagicType.Ice, MagicType.Lightning)] MagicType spellType, [Values(MagicType.Wind, MagicType.Earth, MagicType.Water)] MagicType reflectType) { const int spellCost = 5; const int spellPower = 5; const int expectedRemainingHealth = 100 - spellPower; Spell spell = new Spell("foo", spellType, SpellType.Attack, TargetType.SingleEnemy, spellCost, spellPower); BattleMove runawayMove = MoveFactory.Get(BattleMoveType.Runaway); ReflectStatus status = new ReflectStatus(1, reflectType); _human.SetHealth(100); _human.SetMana(spellCost); _human.SetMagicStrength(0); _human.SetMagicBonus(spellType, 0); _human.SetMagicResistance(0); _human.SetResistanceBonus(spellType, 0); _human.AddSpell(spell); _human.SetMove(spell, 1); _human.SetMove(runawayMove); _human.SetMoveTarget(_enemy); _enemy.AddStatus(status); _enemy.SetHealth(100); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.AreEqual(_human.MaxHealth, _human.CurrentHealth, "human should still have full health, the spell should not have been reflected!"); Assert.AreEqual(expectedRemainingHealth, _enemy.CurrentHealth, "the enemy should have lost 5 health from being hit by the spell!"); }
public void CastSpell_SpellsVanishIfReflectedTwice([Values(MagicType.Fire, MagicType.Ice, MagicType.Lightning)] MagicType spellType, [Values(true, false)] bool reflectAll) { const int spellCost = 5; const int spellPower = 5; Spell spell = new Spell("foo", spellType, SpellType.Attack, TargetType.SingleEnemy, spellCost, spellPower); BattleMove runawayMove = MoveFactory.Get(BattleMoveType.Runaway); MagicType reflectType = reflectAll ? MagicType.All : spellType; ReflectStatus status = new ReflectStatus(1, reflectType); _human.SetHealth(100); _human.SetMana(spellCost); _human.AddStatus(status); _human.AddSpell(spell); _human.SetMove(spell, 1); _human.SetMove(runawayMove); _human.SetMoveTarget(_enemy); _enemy.AddStatus(status); _enemy.SetHealth(100); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.AreEqual(_enemy.MaxHealth, _enemy.CurrentHealth, "enemy should still have full health, the spell should have disappeared without hurting anyone!"); Assert.AreEqual(_human.MaxHealth, _human.CurrentHealth, "the human should still have full health, the spell should have disappeared without hurting anyone"); }
public void CastSpell_CorrectlyReflectsSpells_WithCorrectMultiplier([Values(MagicType.Water, MagicType.Earth, MagicType.Wind)] MagicType spellType, [Values(true, false)] bool reflectAll) { const int spellCost = 5; const int spellPower = 5; const int expectedRemainingHealth = 100 - (spellPower * 2); Spell spell = new Spell("foo", spellType, SpellType.Attack, TargetType.SingleEnemy, spellCost, spellPower); BattleMove runawayMove = MoveFactory.Get(BattleMoveType.Runaway); MagicType reflectType = reflectAll ? MagicType.All : spellType; ReflectStatus status = new ReflectStatus(1, reflectType, 2); _human.SetHealth(100); _human.SetMana(spellCost); _human.AddSpell(spell); _human.SetMove(spell, 1); _human.SetMove(runawayMove); _human.SetMoveTarget(_enemy); _enemy.AddStatus(status); _enemy.SetHealth(100); _battleManager.Battle(_humanTeam, _enemyTeam); Assert.AreEqual(_enemy.MaxHealth, _enemy.CurrentHealth, "enemy should still have full health, the spell should have been reflected!"); Assert.AreEqual(expectedRemainingHealth, _human.CurrentHealth, $"the human should have lost {spellPower * 2} health from being hit by their own spell reflected at double the power!"); }
/// <summary> /// Conducts the OpenSauce & HAC2 data backup routines. /// </summary> /// <param name="backupDir"> /// Backup directory to use for backing up OpenSauce & HAC2 data. /// </param> private void CommitBackups(string backupDir) { Directory.CreateDirectory(backupDir); var OSIDEbackupDir = Path.Combine(backupDir, OpenSauceDeveloper); new List <Move> { MoveFactory.Get(MoveFactory.Type.BackupOsFiles, _path, backupDir), MoveFactory.Get(MoveFactory.Type.BackupOsDirectories, _path, backupDir), MoveFactory.Get(MoveFactory.Type.BackupHac2Files, _path, backupDir) }.ForEach(move => move.Commit()); if (Directory.Exists(Paths.KStudios)) { Copy.All(Paths.KStudios, OSIDEbackupDir); try { Directory.Delete(Paths.KStudios, true); } catch (UnauthorizedAccessException) { /// <see cref="https://stackoverflow.com/a/31363010/14894786"/> /// <seealso cref="https://stackoverflow.com/a/8055390/14894786"/> var batPath = Path.Combine(Paths.Temp, "AdminDelKorn.bat"); var batText = "del /s /q \"Kornner Studios\" && rmdir /s /q \"Kornner Studios\""; File.WriteAllText(batPath, batText); new System.Diagnostics.ProcessStartInfo { FileName = batPath, Verb = "RunAs", WorkingDirectory = Paths.ProgData }; } } }
public void MoveFactory_SmokeTest() { BattleMove ret = null; Assert.DoesNotThrow(() => ret = MoveFactory.Get(BattleMoveType.ShieldBuster)); Assert.NotNull(ret); }
public void CorrectlyRenamesEnemiesIfMultipleEnemiesOfSameType() { _menuInput.Push("Goblin A"); var ret = _menu.GetInput(MoveFactory.Get(BattleMoveType.Attack), null); Assert.AreEqual(_enemyTeam.Fighters[0], ret.Target); }
public void TargetMenu_CorrectlyHandlesBackOption() { //should result in an error _menuInput.Push("back"); var ret = _menu.GetInput(MoveFactory.Get(BattleMoveType.Attack), null); Assert.AreEqual("back", ret.Description); }
/// <summary> /// Conducts the OpenSauce & HAC2 data backup routines. /// </summary> /// <param name="backupDir"> /// Backup directory to use for backing up OpenSauce & HAC2 data. /// </param> private void CommitBackups(string backupDir) { Directory.CreateDirectory(backupDir); new List <Move> { MoveFactory.Get(MoveFactory.Type.BackupOsFiles, _path, backupDir), MoveFactory.Get(MoveFactory.Type.BackupOsDirectories, _path, backupDir), MoveFactory.Get(MoveFactory.Type.BackupHac2Files, _path, backupDir) }.ForEach(move => move.Commit()); }
public void TestUndoDebuffsEffect_IndividualEffect() { StatMultiplierStatus lowerAttackStatus = new StatMultiplierStatus(3, StatType.Strength, 1.0 / 3); StatusMove lowerEnemyAttackMove = new StatusMove("raise attack", TargetType.SingleEnemy, lowerAttackStatus); UndoDebuffsStatus undoDebuffStatus = new UndoDebuffsStatus(1); StatusMove undoDebuffMove = new StatusMove("reset stats", TargetType.SingleAlly, undoDebuffStatus); TestHumanFighter fighter2 = new TestHumanFighter("foo 2", 1); _humanTeam = new TestTeam(_humanFighter, fighter2); //enemy won't be killed if the status isn't assigned to _fighter2 _enemy.SetHealth(3); _enemy.SetSpeed(2); _enemy.SetMove(lowerEnemyAttackMove); _chanceService.PushEventOccurs(true); //status hits _enemy.SetMoveTarget(fighter2); _humanFighter.SetSpeed(1); _humanFighter.SetMove(undoDebuffMove); _chanceService.PushEventOccurs(true); //status hits _humanFighter.SetMoveTarget(fighter2); _logger.Subscribe(EventType.StatusAdded, fighter2); _logger.Subscribe(EventType.StatusRemoved, fighter2); BattleMove attack = MoveFactory.Get(BattleMoveType.Attack); fighter2.SetStrength(3); fighter2.SetMove(attack); fighter2.SetMoveTarget(_enemy); _chanceService.PushEventOccurs(true); //attack hits _chanceService.PushEventOccurs(false); //attack is not a crit //once Statuses are removed after battle, won't be able to _battleManager.Battle(_humanTeam, _enemyTeam); List <EventLog> logs = _logger.Logs; Assert.AreEqual(2, logs.Count); EventLog log = logs[1]; Assert.AreEqual(EventType.StatusRemoved, log.Type); StatusRemovedEventArgs e = log.E as StatusRemovedEventArgs; Assert.NotNull(e); Assert.IsTrue(lowerAttackStatus.AreEqual(e.Status)); }
public void SetUp() { _input = new MockInput(); _output = new MockOutput(); _menuManager = new TestMenuManager(_input, _output); _chanceService = new MockChanceService(); _battleManager = new BattleManager(_chanceService, _input, _output); _human = (TestHumanFighter)TestFighterFactory.GetFighter(TestFighterType.TestHuman, 1); _humanTeam = new TestTeam(_menuManager, _human); _enemy = (TestEnemyFighter)TestFighterFactory.GetFighter(TestFighterType.TestEnemy, 1); _enemyTeam = new Team(_menuManager, _enemy); _doNothingMove = (DoNothingMove)MoveFactory.Get(BattleMoveType.DoNothing); }
private static IEnumerable <BattleMove> GetRegionMovesForRegion(WorldRegion region) { BattleMove[] ret; switch (region) { case WorldRegion.Desert: ret = new[] { MoveFactory.Get(BattleMoveType.ShieldBuster), MoveFactory.Get(BattleMoveType.Attack, "feint") }; break; default: ret = new BattleMove[0]; break; } return(ret); }
public void CorrectlySetsUpMenuForHumanPlayer() { BattleMove doNothing = MoveFactory.Get(BattleMoveType.DoNothing); BattleMove shieldMove = MoveFactory.Get(BattleMoveType.Shield, "iron shield"); _player.AddMove(doNothing); _player.AddMove(shieldMove); _menu.Build(_player, _playerTeam, _enemyTeam, null); List <MenuAction> menuActions = _menu.MenuActions; Assert.AreEqual(2, menuActions.Count); Assert.True(menuActions.Exists(ma => ma.BattleMove == doNothing)); Assert.True(menuActions.Exists(ma => ma.BattleMove == shieldMove)); }
public void AllSpecialMoves_CorrectlyCombinesSpecialMoves_AndExtraSpecialMoveLists() { Assert.AreEqual(0, _fighter.SpecialMoves.Count); Assert.AreEqual(0, _fighter.AllSpecialMoves.Count); BattleMove doNothingMove = MoveFactory.Get(BattleMoveType.DoNothing); BattleMove shieldBusterMove = MoveFactory.Get(BattleMoveType.ShieldBuster); _fighter.AddMove(doNothingMove); //will be added to "extra special move" property _fighter.AddMove(shieldBusterMove); //will be added to "special move" property Assert.AreEqual(1, _fighter.SpecialMoves.Count); Assert.Contains(shieldBusterMove, _fighter.SpecialMoves); Assert.AreEqual(2, _fighter.AllSpecialMoves.Count); Assert.Contains(doNothingMove, _fighter.AllSpecialMoves); Assert.Contains(shieldBusterMove, _fighter.AllSpecialMoves); }
public void StatusTechnique_AppropriatelyAssignsStatusToTarget() { StatMultiplierStatus status = new StatMultiplierStatus(3, StatType.Strength, 1.5); StatusMove statusMove = new StatusMove("raise attack", TargetType.SingleAlly, status); TestHumanFighter fighter2 = new TestHumanFighter("foo 2", 1); _humanTeam = new TestTeam(_humanFighter, fighter2); _humanFighter.SetSpeed(1); _humanFighter.SetMove(statusMove); _chanceService.PushEventOccurs(true); _humanFighter.SetMoveTarget(fighter2); _logger.Subscribe(EventType.StatusAdded, fighter2); BattleMove attack = MoveFactory.Get(BattleMoveType.Attack); fighter2.SetStrength(2); fighter2.SetMove(attack); fighter2.SetMoveTarget(_enemy); _chanceService.PushEventOccurs(true); //attack hits _chanceService.PushEventOccurs(false); //attack is not a crit //enemy won't be killed if the status isn't assigned to _fighter2 _enemy.SetHealth(3); _enemy.SetMove(_doNothing); _enemy.SetMoveTarget(_enemy); //once Statuses are removed after battle, won't be able to _battleManager.Battle(_humanTeam, _enemyTeam); List <EventLog> logs = _logger.Logs; Assert.AreEqual(1, logs.Count); EventLog log = logs[0]; Assert.AreEqual(EventType.StatusAdded, log.Type); StatusAddedEventArgs e = log.E as StatusAddedEventArgs; Assert.NotNull(e); Assert.IsTrue(status.AreEqual(e.Status)); }
public void AddMove_AppropriatelyRaisesEvent_SpecialMove() { BattleMove shieldMove = MoveFactory.Get(BattleMoveType.Shield, "iron shield"); _fighter.AddMove(shieldMove); List <EventLog> logs = _logger.Logs; Assert.AreEqual(1, logs.Count); EventLog log = logs[0]; Assert.AreEqual(EventType.MoveLearned, log.Type); MoveLearnedEventArgs e = log.E as MoveLearnedEventArgs; Assert.NotNull(e); Assert.AreEqual(shieldMove, e.Move); }
/// <summary> /// Conducts optional installation finalisation routines. /// - Restore the HCE shaders. /// - Move the OpenSauce IDE. /// - Backup directory cleanup. /// </summary> /// <param name="backupDir"></param> private void FinishInstall(string backupDir) { // restore backed up HCE shaders MoveFactory.Get(MoveFactory.Type.RestoreHceShaders, _path, backupDir).Commit(); var source = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), FileNames.OpenSauceDeveloper, FileNames.OpenSauceDirectory, FileNames.OpenSauceIDE); var target = Path.Combine(_path, FileNames.OpenSauceIDE); Copy.All(new DirectoryInfo(source), new DirectoryInfo(target)); Directory.Delete(source, true); // cleans up backup directory if (!Directory.EnumerateFileSystemEntries(backupDir).Any()) { Directory.Delete(backupDir); } }
/// <summary> /// Conducts optional installation finalisation routines. /// - Restore the HCE shaders. /// - Move the OpenSauce IDE. /// - Empty backup directory cleanup. /// </summary> /// <param name="backupDir"></param> private void FinishInstall(string backupDir) { // restore backed up HCE shaders MoveFactory.Get(MoveFactory.Type.RestoreHceShaders, _path, backupDir) .Commit(); // copy OS IDE to Install path var source = Path.Combine(Paths.KStudios, OpenSauceDirectory, OpenSauceIDE); var target = Path.Combine(_path, OpenSauceIDE); Copy.All(source, target); // cleans up empty backup directory if (!Directory.EnumerateFileSystemEntries(backupDir).Any()) { Directory.Delete(backupDir); } }
private static bool Foo() { SelectEnemyTeamMenuManager enemyTeamGenerator = new SelectEnemyTeamMenuManager(Globals.Input, Globals.Output); BattleConfigurationSpecialFlag battleFlag; Team enemyTeam = enemyTeamGenerator.GetTeam(new MenuManager(Globals.Input, Globals.Output, Globals.MenuFactory), Globals.Input, Globals.Output, out battleFlag); NumberInputMenu levelInputMenu = new NumberInputMenu("What levels will your fighters be (min 1. Max 5)?", Globals.Input, Globals.Output, 1, 5); NumberInputMenuSelection levelInput = levelInputMenu.GetInput() as NumberInputMenuSelection; if (levelInput == null) { throw new Exception("something went terribly wrong, a NumberInputMenu did not return a NumberInputMenuSelection"); } int level = levelInput.Number; var playerOne = (HumanFighter)FighterFactory.GetFighter(FighterType.HumanControlledPlayer, level, "Dante"); var playerTwo = (HumanFighter)FighterFactory.GetFighter(FighterType.HumanControlledPlayer, level, "Arrokoh"); var playerTeam = new Team(new MenuManager(Globals.Input, Globals.Output, Globals.MenuFactory), playerOne, playerTwo); BattleMove doNothing = MoveFactory.Get(BattleMoveType.DoNothing); BattleMove feintAttack = MoveFactory.Get(BattleMoveType.Attack, "feint"); BattleMove shieldBuster = MoveFactory.Get(BattleMoveType.ShieldBuster); foreach (HumanFighter fighter in playerTeam.Fighters) { fighter.AddMove(doNothing); fighter.AddMove(feintAttack); fighter.AddMove(shieldBuster); } FakeBattleManager manager = new FakeBattleManager(Globals.ChanceService, Globals.Input, Globals.Output); manager.Battle(playerTeam, enemyTeam, config: new BattleManagerBattleConfiguration { SpecialBattleFlag = battleFlag }); return(true); }
public void SetUp() { _input = new MockInput(); _output = new MockOutput(); _menuManager = new TestMenuManager(_input, _output); _chanceService = new MockChanceService(); _battleManager = new BattleManager(_chanceService, _input, _output); _human = (TestHumanFighter)TestFighterFactory.GetFighter(TestFighterType.TestHuman, 1); _humanTeam = new TestTeam(_menuManager, _human); _enemy = (TestEnemyFighter)TestFighterFactory.GetFighter(TestFighterType.TestEnemy, 1); _enemyTeam = new Team(_menuManager, _enemy); _doNothingMove = (DoNothingMove)MoveFactory.Get(BattleMoveType.DoNothing); _restoreHealthEffect = new RestorationBattleMoveEffect(RestorationType.Health, 5, BattleMoveEffectActivationType.OnAttackHit); _attackWithRestoreHealthEffect = new AttackBattleMove("foo", TargetType.SingleEnemy, 100, 10, effects: _restoreHealthEffect); _restoreManaEffect = new RestorationBattleMoveEffect(RestorationType.Mana, 5, BattleMoveEffectActivationType.OnAttackHit); _attackWithRestoreManaEffect = new AttackBattleMove("foo", TargetType.SingleEnemy, 100, 10, effects: _restoreManaEffect); }
public void TargetMenu_DoesNotDisplayDefeatedEnemies() { var enemy = _enemyTeam.Fighters[0]; enemy.PhysicalDamage(enemy.MaxHealth); //should result in an error _menuInput.Push("Goblin A"); _menuInput.Push("Goblin B"); var ret = _menu.GetInput(MoveFactory.Get(BattleMoveType.Attack), null); Assert.AreEqual(_enemyTeam.Fighters[1], ret.Target); var outputs = _menuOutput.GetOutputs(); //5 for each time menu is printed (prompt, only one enemy displayed, back prompt, help prompt, status prompt) //1 for error message Assert.AreEqual(11, outputs.Length); Assert.AreEqual(MockOutputMessageType.Error, outputs[5].Type); }
public void SelectMove_MultiTurnMoveSelected() { var enemy = (TestEnemyFighter)TestFighterFactory.GetFighter(TestFighterType.TestEnemy, 1); var enemyTeam = new Team(_menuManager, enemy); var human = (TestHumanFighter)TestFighterFactory.GetFighter(TestFighterType.TestHuman, 1); var humanTeam = new Team(_menuManager, human); var fooMove = new DoNothingMove("Foo!"); var barMove = new DoNothingMove("Bar!"); var bazMove = new AttackBattleMove("Baz", TargetType.SingleEnemy, 50, 100); var multiTurnMove = new MultiTurnBattleMove("multi turn move", TargetType.SingleEnemy, fooMove, barMove, bazMove); enemy.SetAvailableMove(multiTurnMove); var selectedMove = enemy.SetupMove(enemyTeam, humanTeam); Assert.AreEqual(multiTurnMove, selectedMove.Move); var attack = MoveFactory.Get(BattleMoveType.Attack); enemy.SetAvailableMove(attack); selectedMove = enemy.SetupMove(enemyTeam, humanTeam); Assert.AreEqual(barMove, selectedMove.Move); selectedMove = enemy.SetupMove(enemyTeam, humanTeam); Assert.AreEqual(bazMove, selectedMove.Move); selectedMove = enemy.SetupMove(enemyTeam, humanTeam); Assert.AreEqual(attack, selectedMove.Move); }
/// <summary> /// Fake moves include targetType = self/description = "test" for a test self-target /// moveType = "Special" and description = "test" for a test special move (target type field) /// and description = "testMultiTurn" to get a fake multi-turn move (2 turns do nothing, 3rd turn attack) /// </summary> /// <param name="targetType"></param> /// <param name="description"></param> /// <param name="moveType"></param> /// <returns></returns> public static BattleMove Get(TargetType targetType = TargetType.Self, string description = "test", BattleMoveType?moveType = null) { BattleMove ret; if (description == "test") { if (targetType == TargetType.Self && moveType == null) { ret = FakeSelfTargetMove; } else if (targetType == TargetType.SingleAlly || targetType == TargetType.SingleAllyOrSelf) { ret = new BattleMove(description, BattleMoveType.DoNothing, targetType); } else if (!moveType.HasValue) { throw new ArgumentException( "Either TargetType self must be specified or a valid moveType must be given"); } else { switch (moveType.Value) { case BattleMoveType.Special: ret = FakeSpecialMove; break; case BattleMoveType.DoNothing: ret = new TestDoNothingMove(); break; case BattleMoveType.Field: ret = new TestFieldEffectMove("foo", TargetType.OwnTeam, 2); break; case BattleMoveType.Dance: ret = new TestDanceMove("foo dance", TargetType.Field, 0); break; default: throw new ArgumentException( $"No test move found for the given inputs. TargetType: '{targetType}', moveType: '{moveType}'"); } } } else if (description == "testMultiTurn") { ret = FakeMultiTurnMove; } else if (moveType == null) { throw new ArgumentException( "TestMoveFactory.Get() must either specify a moveType, or indicate it wants a test move!"); } else { ret = MoveFactory.Get(moveType.Value); } return(ret); }
public override void Build(IFighter owner, Team ownTeam, Team enemyTeam, List <TerrainInteractable> terrainInteractables) { MenuActions = new List <MenuAction> { new MenuAction("attack", subMenu: _menuFactory.GetMenu(MenuType.ChooseTargetMenu, _input, _output), move: MoveFactory.Get(BattleMoveType.Attack)) }; if (owner.Spells.Any()) { MenuActions.Add(new MenuAction("magic", subMenu: _menuFactory.GetMenu(MenuType.ChooseSpellMenu, _input, _output))); } if (owner.SpecialMoves.Any()) { //MenuActions.Add(new MenuAction("special move", altText: "special")); MenuActions.Add(new MenuAction("special move", altText: "special", subMenu: _menuFactory.GetMenu(MenuType.ChooseSpecialAttackMenu, _input, _output))); } base.Build(owner, ownTeam, enemyTeam, terrainInteractables); }