bool cleanseRoster(TroopRoster roster) { bool removed = false; // search for corrupted troops in the internal member "data" of TroopRoster TroopRosterElement[] troops = (TroopRosterElement[])roster.GetType().GetField("data", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(roster); var characterObjects = troops.Where(t => t.Number > 0 && t.Character?.Age == 0f).Select(t => t.Character).ToList(); if (characterObjects.Any()) { // delete them foreach (CharacterObject troop in characterObjects) { roster.RemoveTroop(troop, roster.GetTroopCount(troop)); removed = true; } } return(removed); }
private static void SortRoster(SorterConfiguration configuration, TroopRoster troopRoster, ICollection <PartyCharacterVM> partyList, Action <MBBindingList <PartyCharacterVM> > apply) { FieldInfo troopRosterDataField = troopRoster.GetType().GetField("data", BindingFlags.NonPublic | BindingFlags.Instance); TroopRosterElement[] originalTroops = (TroopRosterElement[])troopRosterDataField?.GetValue(troopRoster); if (originalTroops == null || originalTroops.All(x => x.Character == null)) { return; } List <TroopRosterElement> originalTroopList = originalTroops.Where(x => x.Character != null).ToList(); List <TroopRosterElement> sortedTroops = originalTroopList.Where(x => !x.Character.IsHero).ToList(); List <TroopRosterElement> heroTroops = originalTroopList.Where(x => x.Character.IsHero && !x.Character.IsPlayerCharacter).ToList(); TroopRosterElement player = originalTroopList.FirstOrDefault(x => x.Character.IsPlayerCharacter); TroopSorterService.Sort(ref sortedTroops, ref heroTroops, configuration); if (heroTroops.Count > 0) { sortedTroops.InsertRange(0, heroTroops); } if (player.Character != null) { sortedTroops.Insert(0, player); } troopRosterDataField.SetValue(troopRoster, sortedTroops.ToArray()); List <PartyCharacterVM> tempTroopList = partyList.ToList(); MBBindingList <PartyCharacterVM> newTroopList = new MBBindingList <PartyCharacterVM>(); partyList.Clear(); foreach (PartyCharacterVM troop in sortedTroops.Select(sortedTroop => tempTroopList.FirstOrDefault(x => x.Troop.Character.ToString() == sortedTroop.Character.ToString()))) { newTroopList.Add(troop); } apply(newTroopList); }
static void Postfix(TroopRoster __instance, CharacterObject troop, int numberToWound, UniqueTroopDescriptor troopSeed) { try { //Reflection gimmicks to get "internal PartyBase OwnerParty" from TroopRoster PropertyInfo prop = __instance.GetType().GetProperty("OwnerParty", BindingFlags.NonPublic | BindingFlags.Instance); PartyBase OwnerParty = (PartyBase)prop.GetValue(__instance); if (troop.IsHero) { Hero heroTroop = troop.HeroObject; float xpValue = WoundXpSubModule.settings.HeroWoundXpValue; DefaultCharacterDevelopmentModel characterDevelopmentModel = new DefaultCharacterDevelopmentModel(); float learningRateBonus = characterDevelopmentModel.CalculateLearningRate(heroTroop, DefaultSkills.Athletics); if (WoundXpSubModule.settings.ScalableSkillXp) { xpValue *= (float)Math.Round(learningRateBonus, 1); } heroTroop.AddSkillXp(DefaultSkills.Athletics, xpValue); if (WoundXpSubModule.settings.DebugInfo || troop.IsPlayerCharacter || heroTroop.IsPlayerCompanion) { if (WoundXpSubModule.settings.ScalableSkillXp) { WoundXpSubModule.Log.Info("Hero Troop: " + troopSeed.ToString() + " | Calculated learning rate bonus = " + learningRateBonus.ToString()); if (WoundXpSubModule.settings.DebugInfo && WoundXpSubModule.settings.ReceivedXpInConsole) { InformationManager.DisplayMessage(new InformationMessage(heroTroop.Name + " calculated learning rate bonus = " + learningRateBonus.ToString(), Colors.Yellow)); } } if (WoundXpSubModule.settings.ReceivedXpInConsole) { InformationManager.DisplayMessage(new InformationMessage(heroTroop.Name + " received " + xpValue + " Athletics XP for surviving after being wounded.", Colors.Yellow)); } WoundXpSubModule.Log.Info("Hero Troop: " + troopSeed.ToString() + " | " + heroTroop.Name + " received Athletics XP value of " + xpValue); } } else { int xpValue = WoundXpSubModule.settings.TroopWoundXpValue; int troopTierBonus = troop.Tier + 1; if (WoundXpSubModule.settings.ScalableSkillXp) { xpValue *= troopTierBonus; } __instance.AddXpToTroop(xpValue, troop); if (WoundXpSubModule.settings.DebugInfo || OwnerParty.Owner != null && OwnerParty.Owner.IsHumanPlayerCharacter) { if (WoundXpSubModule.settings.ScalableSkillXp) { WoundXpSubModule.Log.Info("Generic Troop: " + troopSeed.ToString() + " | Calculated learning troop tier bonus = " + troopTierBonus.ToString()); if (WoundXpSubModule.settings.DebugInfo && WoundXpSubModule.settings.ReceivedXpInConsole) { InformationManager.DisplayMessage(new InformationMessage(troop.Name + " calculated troop tier bonus = " + troopTierBonus.ToString(), Colors.Yellow)); } } if (WoundXpSubModule.settings.ReceivedXpInConsole) { InformationManager.DisplayMessage(new InformationMessage(troop.Name + " received " + xpValue + " XP for surviving after being wounded.", Colors.Yellow)); } WoundXpSubModule.Log.Info("Generic Troop: " + troopSeed.ToString() + " | " + troop.Name + " received XP value of " + xpValue); } } } catch (Exception ex) { WoundXpSubModule.Log.Error("Error on Harmony Patch for WoundTroop. | " + ex.Message); InformationManager.DisplayMessage(new InformationMessage("Something went wrong with Iron Will - Wound Experience: " + ex.Message, Colors.Red)); } }