private void GetSavingThrows() { if (SavingThrows.Contains("Str")) { StrSavingThrow = true; } if (SavingThrows.Contains("Dex")) { DexSavingThrow = true; } if (SavingThrows.Contains("Con")) { ConSavingThrow = true; } if (SavingThrows.Contains("Int")) { IntSavingThrow = true; } if (SavingThrows.Contains("Wis")) { WisSavingThrow = true; } if (SavingThrows.Contains("Cha")) { ChaSavingThrow = true; } }
public string FindSavingThrow(Dictionaries.Attributes input) { if (SavingThrows.Count != 0) { if (SavingThrows.Contains(input)) { StringBuilder output = new StringBuilder(); foreach (Dictionaries.Attributes SavingThrow in SavingThrows) { if (input == SavingThrow) { output.AppendLine($"{SavingThrow}"); } } return(output.ToString()); } else { return("This saving throw is not in this list"); } } else { return("The list of saving throws is empty"); } }
public void Level1BardReturns0() { SavingThrows Fort = new SavingThrows(); int expected = 0; int actual = Fort.GetFort(1, "Bard"); Assert.AreEqual(expected, actual); }
public void Level20PaladinReturns12() { SavingThrows Fort = new SavingThrows(); int expected = 12; int actual = Fort.GetFort(20, "Paladin"); Assert.AreEqual(expected, actual); }
public void Level20PaladinReturns12Will() { SavingThrows will = new SavingThrows(); int expected = 6; int actual = will.GetWill(20, "Paladin"); Assert.AreEqual(expected, actual); }
public void BadDataReturnsErrorWill() { SavingThrows will = new SavingThrows(); int expected = -999; int actual = will.GetWill(21, "Paladin"); Assert.AreEqual(expected, actual); }
public void BadDataReturnsErrorReflex() { SavingThrows reflex = new SavingThrows(); int expected = -999; int actual = reflex.GetReflex(21, "Paladin"); Assert.AreEqual(expected, actual); }
public void Level1BardReturns0Will() { SavingThrows will = new SavingThrows(); int expected = 2; int actual = will.GetWill(1, "Bard"); Assert.AreEqual(expected, actual); }
public void Level20PaladinReturns6Reflex() { SavingThrows reflex = new SavingThrows(); int expected = 6; int actual = reflex.GetReflex(20, "Paladin"); Assert.AreEqual(expected, actual); }
public void Level1BardReturns2Reflex() { SavingThrows reflex = new SavingThrows(); int expected = 2; int actual = reflex.GetReflex(1, "Bard"); Assert.AreEqual(expected, actual); }
public void BadDataReturnsError() { SavingThrows Fort = new SavingThrows(); int expected = -999; int actual = Fort.GetFort(21, "Paladin"); Assert.AreEqual(expected, actual); }
public string SavingThrowBonus(int abilityId) { var bonus = AbilityScores.Single(n => n.AbilityId == abilityId).Bonus; var proficiencyBonus = SavingThrows.Contains(abilityId) ? _ProficiencyBonus : 0; var total = bonus + proficiencyBonus; return((total >= 0 ? "+" : null) + total.ToString()); }
public override void AddProficiencies() { ProficientArmors = new List <string>(new string[] { "Light Armor", "Medium Armor", "Shields" }); ProficientWeapons.AddRange(Equipment.SimpleMeleeWeapons); ProficientWeapons.AddRange(Equipment.SimpleRangedWeapons); ProficientTools.Add("None"); SavingThrows.Add("Wisdom"); SavingThrows.Add("Charisma"); }
public virtual void AssignThrows() { SavingThrows.FortAbilitySavingThrow = StatMods.ConAbilityMod; SavingThrows.ReflexAbilitySavingThrow = StatMods.DexAbilityMod; SavingThrows.WillAbilitySavingThrow = StatMods.WisAbilityMod; SavingThrows.FortClassSavingThrow = SavingThrows.GetFort(PlayerLevel, ChosenClass); SavingThrows.ReflexClassSavingThrow = SavingThrows.GetReflex(PlayerLevel, ChosenClass); SavingThrows.WillClassSavingThrow = SavingThrows.GetWill(PlayerLevel, ChosenClass); }
public override void AddProficiencies() { ProficientWeapons.AddRange(Equipment.SimpleMeleeWeapons); ProficientWeapons.AddRange(Equipment.MartialMeleeWeapons); ProficientWeaponTypes.Add("Simple Melee Weapons"); ProficientWeaponTypes.Add("Martial Melee Weapons"); ProficientArmors = new List <string>(new string[] { "Light Armor", "Medium Armor", "Shields" }); ProficientTools.Add("None"); SavingThrows.Add("Strength"); SavingThrows.Add("Constitution"); }
public override void AddProficiencies() { ProficientArmors.Add(""); ProficientArmors.Add("Shield"); ProficientWeapons.AddRange(Equipment.SimpleMeleeWeapons); ProficientWeapons.AddRange(Equipment.SimpleRangedWeapons); ProficientWeapons.AddRange(Equipment.MartialMeleeWeapons); ProficientWeapons.AddRange(Equipment.MartialRangedWeapons); ProficientTools.Add("None"); SavingThrows.Add("Strength"); SavingThrows.Add("Constitution"); }
public bool RemoveSavingThrow(Dictionaries.Attributes input) { if (SavingThrows.Contains(input)) { SavingThrows.Remove(input); return(true); } else { return(false); } }
public override void AddProficiencies() { ProficientWeapons.AddRange(Equipment.SimpleMeleeWeapons); ProficientWeapons.Add("Crossbow, hand"); ProficientWeapons.Add("Longsword"); ProficientWeapons.Add("Rapier"); ProficientWeapons.Add("Shortsword"); ProficientWeaponTypes = new List <string>(new[] { "Simple Melee Weapons", "Crossbow, Hand", "Longsword", "Rapier", "Shortsword" }); ProficientArmors = new List <string>(new string[] { "Light Armor" }); ProficientTools.Add("First Instrument of Your Choice"); ProficientTools.Add("Second Instrument of Your Choice"); ProficientTools.Add("Third Instrument of Your Choice"); SavingThrows.Add("Dexterity"); SavingThrows.Add("Charisma"); }
public override void AddProficiencies() { ProficientArmors = new List <string>(new[] { "Light Armor", "Medium Armor", "Shields", "(Druids will not wear armor or use shields made of metal)" }); ProficientWeapons.Add("Club"); ProficientWeapons.Add("Dagger"); ProficientWeapons.Add("Dart"); ProficientWeapons.Add("Javelin"); ProficientWeapons.Add("Mace"); ProficientWeapons.Add("Quarterstaff"); ProficientWeapons.Add("Scimitar"); ProficientWeapons.Add("Sickle"); ProficientWeapons.Add("Sling"); ProficientWeapons.Add("Spear"); ProficientTools.Add("Herbalism Kit"); SavingThrows.Add("Intelligence"); SavingThrows.Add("Wisdom"); }
public Combat() { ArmorClass = new ArmorClass(); SavingThrows = new SavingThrows(); BaseAttack = new BaseAttack(); }
public static void Prefix(AttackStackSequence __instance, MessageCenterMessage message) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (ShouldSkipProcessing(__instance, message)) { return; } if (!(message is AttackCompleteMessage attackCompleteMessage)) { return; } var director = __instance.directorSequences; if (director == null) { return; } LogReport(new string('═', 46)); LogReport($"{director[0].attacker.DisplayName} attacks {director[0].chosenTarget.DisplayName}"); // get the attacker in case they have mech quirks AbstractActor defender = null; switch (director[0]?.chosenTarget) { case Vehicle _: defender = (Vehicle)director[0]?.chosenTarget; break; case Mech _: defender = (Mech)director[0]?.chosenTarget; break; } // a building? if (defender == null) { LogDebug("Not a mech or vehicle"); return; } var attacker = director[0].attacker; var index = GetActorIndex(defender); if (!ShouldPanic(defender, attackCompleteMessage.attackSequence)) { return; } // automatically eject a klutzy pilot on knockdown with an additional roll failing on 13 if (defender.IsFlaggedForKnockdown) { var defendingMech = (Mech)defender; if (defendingMech.pilot.pilotDef.PilotTags.Contains("pilot_klutz")) { if (Random.Range(1, 100) == 13) { defender.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage (new ShowActorInfoSequence(defender, "WOOPS!", FloatieMessage.MessageNature.Debuff, false))); LogReport("Very klutzy!"); return; } } } // store saving throw // check it against panic // check it again ejection var savingThrow = SavingThrows.GetSavingThrow(defender, attacker); Mech_AddExternalHeat_Patch.heatDamage = 0; // panic saving throw if (SavingThrows.SavedVsPanic(defender, savingThrow)) { return; } // stop if pilot isn't Panicked if (TrackedActors[index].PanicStatus != PanicStatus.Panicked) { return; } // eject saving throw if (SavingThrows.SavedVsEject(defender, savingThrow)) { return; } // ejecting // random phrase if (modSettings.EnableEjectPhrases && defender is Mech && Random.Range(1, 100) <= modSettings.EjectPhraseChance) { var ejectMessage = ejectPhraseList[Random.Range(1, ejectPhraseList.Count)]; defender.Combat.MessageCenter.PublishMessage( new AddSequenceToStackMessage( new ShowActorInfoSequence(defender, $"{ejectMessage}", FloatieMessage.MessageNature.Debuff, true))); } // remove effects, to prevent exceptions that occur for unknown reasons var combat = UnityGameInstance.BattleTechGame.Combat; var effectsTargeting = combat.EffectManager.GetAllEffectsTargeting(defender); foreach (var effect in effectsTargeting) { // some effects removal throw, so silently drop them try { defender.CancelEffect(effect); } catch { // ignored } } if (modSettings.VehiclesCanPanic && defender is Vehicle) { // make the regular Pilot Ejected floatie not appear, for this ejection var original = AccessTools.Method(typeof(BattleTech.VehicleRepresentation), "PlayDeathFloatie"); var prefix = AccessTools.Method(typeof(VehicleRepresentation), nameof(VehicleRepresentation.PrefixDeathFloatie)); harmony.Patch(original, new HarmonyMethod(prefix)); defender.EjectPilot(defender.GUID, attackCompleteMessage.stackItemUID, DeathMethod.PilotEjection, true); harmony.Unpatch(original, HarmonyPatchType.Prefix); defender.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage( new ShowActorInfoSequence(defender, "Crew destroys vehicle!", FloatieMessage.MessageNature.Inspiration, true))); } else { defender.EjectPilot(defender.GUID, attackCompleteMessage.stackItemUID, DeathMethod.PilotEjection, false); } LogReport($"Ejected. Runtime {stopwatch.ElapsedMilliSeconds}ms"); if (!modSettings.CountAsKills) { return; } try { // this seems pretty convoluted var attackerPilot = combat.AllMechs.Where(mech => mech.pilot.Team.IsLocalPlayer) .Where(x => x.PilotableActorDef == attacker.PilotableActorDef).Select(y => y.pilot).FirstOrDefault(); var statCollection = attackerPilot?.StatCollection; if (statCollection == null) { return; } if (defender is Mech) { // add UI icons.. and pilot history? ... MechsKilled already incremented?? statCollection.Set("MechsKilled", attackerPilot.MechsKilled + 1); var value = statCollection.GetStatistic("MechsEjected")?.Value <int?>(); if (statCollection.GetStatistic("MechsEjected") == null) { statCollection.AddStatistic("MechsEjected", 1); } else { statCollection.Set("MechsEjected", value + 1); } // add achievement kill (more complicated) var combatProcessors = Traverse.Create(UnityGameInstance.BattleTechGame.Achievements).Field("combatProcessors").GetValue <AchievementProcessor[]>(); var combatProcessor = combatProcessors.FirstOrDefault(x => x.GetType() == AccessTools.TypeByName("BattleTech.Achievements.CombatProcessor")); // field is of type Dictionary<string, CombatProcessor.MechCombatStats> var playerMechStats = Traverse.Create(combatProcessor).Field("playerMechStats").GetValue <IDictionary>(); if (playerMechStats != null) { foreach (DictionaryEntry kvp in playerMechStats) { if ((string)kvp.Key == attackerPilot.GUID) { Traverse.Create(kvp.Value).Method("IncrementKillCount").GetValue(); } } } } else if (modSettings.VehiclesCanPanic && defender is Vehicle) { var value = statCollection.GetStatistic("VehiclesEjected")?.Value <int?>(); if (statCollection.GetStatistic("VehiclesEjected") == null) { statCollection.AddStatistic("VehiclesEjected", 1); } else { statCollection.Set("VehiclesEjected", value + 1); } } } catch (Exception ex) { LogDebug(ex); } }