protected EnhancedBattleTestAgentOrigin(IBattleCombatant combatant, IEnhancedBattleTestTroopSupplier troopSupplier, BattleSideEnum side, int rank = -1, UniqueTroopDescriptor uniqueNo = default) { _troopSupplier = troopSupplier; _side = side; BattleCombatant = combatant; _descriptor = !uniqueNo.IsValid ? new UniqueTroopDescriptor(TaleWorlds.Core.Game.Current.NextUniqueTroopSeed) : uniqueNo; Rank = rank == -1 ? MBRandom.RandomInt(10000) : rank; }
private LocationCharacter CreateLocationCharacter() { String actionSetCode = "as_human_villager_in_tavern"; UniqueTroopDescriptor uniqueNo = default(UniqueTroopDescriptor); LocationCharacter locationCharacter = new LocationCharacter(new AgentData(new PartyAgentOrigin(null, this._sneaker.CharacterObject, -1, uniqueNo, false)).Monster(Campaign.Current.HumanMonsterSettlement).NoHorses(false), SandBoxManager.Instance.AgentBehaviorManager.AddWandererBehaviors, "sms_npc_sneck", false, LocationCharacter.CharacterRelations.Friendly, actionSetCode, true, false, null, false, false, false); return(locationCharacter); }
// MapEventSide.ApplySimulationDamageToSelectedTroop public static bool ApplySimulationDamageToSelectedTroop(MapEventSide side, CharacterObject strikedTroop, PartyBase strikedTroopParty, UniqueTroopDescriptor strikedTroopDescriptor, int selectedSimulationTroopIndex, List <UniqueTroopDescriptor> strikedTroopList, PartyAttackComposition attack, DamageTypes damageType, PartyBase strikerParty, MapEventState mapEventState, IBattleObserver battleObserver, out float damage) { bool IsFinishingStrike = mapEventState.ApplyDamageToPartyTroop(attack, strikedTroopParty, strikedTroop, out damage); if (IsFinishingStrike) { if (strikedTroop.IsHero) { battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); } else { float survivalChance = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(strikedTroopParty, strikedTroop, damageType, strikerParty); if (MBRandom.RandomFloat < survivalChance) { side.OnTroopWounded(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 1f); } } else { side.OnTroopKilled(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 1, 0, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 0.5f); } } } // side.RemoveSelectedTroopFromSimulationList(); RemoveSelectedTroopFromSimulationList(side, selectedSimulationTroopIndex, strikedTroopList); } return(IsFinishingStrike); }
public CustomBattleAgentOrigin( CustomBattleCombatant customBattleCombatant, BasicCharacterObject characterObject, CustomBattleTroopSupplier troopSupplier, bool isPlayerSide, int rank = -1, UniqueTroopDescriptor uniqueNo = default(UniqueTroopDescriptor)) { this.CustomBattleCombatant = customBattleCombatant; this.Troop = characterObject; this._descriptor = !uniqueNo.IsValid ? new UniqueTroopDescriptor(Game.Current.NextUniqueTroopSeed) : uniqueNo; this.Rank = rank == -1 ? MBRandom.RandomInt(10000) : rank; this._troopSupplier = troopSupplier; this._isPlayerSide = isPlayerSide; }
private static bool StrikeOnce(MapEvent mapEvent, IBattleObserver battleObserver, MapEventSide strikerSide, MapEventSide strikedSide, PartyAttackComposition attack, out float totalDamageDone) { int strikerNumber = strikerSide.NumRemainingSimulationTroops; int strikedNumber = strikedSide.NumRemainingSimulationTroops; totalDamageDone = 0; if (strikerNumber == 0 || strikedNumber == 0) { return(true); } MapEventState mapEventState = MapEventState.GetMapEventState(mapEvent); bool finishedAnyone = false; for (int index = strikedNumber - 1; index >= 0; index--) { UniqueTroopDescriptor strikerTroopDescriptor = strikerSide.SelectRandomSimulationTroop(); CharacterObject strikerTroop = strikerSide.GetAllocatedTroop(strikerTroopDescriptor); PartyBase strikerTroopParty = strikerSide.GetAllocatedTroopParty(strikerTroopDescriptor); UniqueTroopDescriptor strikedTroopDescriptor = MapEventSideHelper.SelectSimulationTroopAtIndex(strikedSide, index, out List <UniqueTroopDescriptor> strikedTroopList); CharacterObject strikedTroop = strikedSide.GetAllocatedTroop(strikedTroopDescriptor); PartyBase strikedTroopParty = strikedSide.GetAllocatedTroopParty(strikedTroopDescriptor); // MapEvents.GetSimulatedDamage and CombatSimulationModel.SimulateHit if (mapEvent.IsPlayerSimulation && strikedTroopParty == PartyBase.MainParty) { float damageMultiplier = Campaign.Current.Models.DifficultyModel.GetPlayerTroopsReceivedDamageMultiplier(); attack *= damageMultiplier; } DamageTypes damageType = (double)MBRandom.RandomFloat < 0.15 ? DamageTypes.Blunt : DamageTypes.Cut; bool isFinishingStrike = MapEventSideHelper.ApplySimulationDamageToSelectedTroop( strikedSide, strikedTroop, strikedTroopParty, strikedTroopDescriptor, index, strikedTroopList, attack, damageType, strikerTroopParty, mapEventState, battleObserver, out float damage); totalDamageDone += damage; strikerSide.ApplySimulatedHitRewardToSelectedTroop(strikedTroop, 0, isFinishingStrike); finishedAnyone = finishedAnyone || isFinishingStrike; } return(finishedAnyone); }
public static UniqueTroopDescriptor SelectSimulationTroopAtIndex(MapEventSide side, int index, out List <UniqueTroopDescriptor> simulationTroopList) { // side._selectedSimulationTroopIndex = index; MapEventSide__selectedSimulationTroopIndex.SetValue(side, index); // side._selectedSimulationTroopDescriptor = side._simulationTroopList[index]; simulationTroopList = (List <UniqueTroopDescriptor>)MapEventSide__simulationTroopList.GetValue(side); UniqueTroopDescriptor selectedSimulationTroopDescriptor = simulationTroopList[index]; MapEventSide__selectedSimulationTroopDescriptor.SetValue(side, selectedSimulationTroopDescriptor); // side._selectedSimulationTroop = side.GetAllocatedTroop(side._selectedSimulationTroopDescriptor); MapEventSide__selectedSimulationTroop.SetValue(side, side.GetAllocatedTroop(selectedSimulationTroopDescriptor)); return(selectedSimulationTroopDescriptor); }
public IEnumerable <IAgentOriginBase> SupplyTroops( int numberToAllocate) { List <BasicCharacterObject> basicCharacterObjectList = this.AllocateTroops(numberToAllocate); CustomBattleAgentOrigin[] battleAgentOriginArray = new CustomBattleAgentOrigin[basicCharacterObjectList.Count]; this._numAllocated += basicCharacterObjectList.Count; for (int index = 0; index < battleAgentOriginArray.Length; ++index) { UniqueTroopDescriptor uniqueNo = new UniqueTroopDescriptor(Game.Current.NextUniqueTroopSeed); battleAgentOriginArray[index] = new CustomBattleAgentOrigin(this._customBattleCombatant, basicCharacterObjectList[index], this, this._isPlayerSide, index, uniqueNo); } if (battleAgentOriginArray.Length < numberToAllocate) { this._anyTroopRemainsToBeSupplied = false; } return((IEnumerable <IAgentOriginBase>)battleAgentOriginArray); }
public IEnumerable <IAgentOriginBase> SupplyTroops( int numberToAllocate) { List <SPSpawnableCharacter> characterList = AllocateTroops(numberToAllocate); EnhancedBattleTestAgentOrigin[] battleAgentOriginArray = new EnhancedBattleTestAgentOrigin[characterList.Count]; _numAllocated += characterList.Count; for (int rank = 0; rank < battleAgentOriginArray.Length; ++rank) { UniqueTroopDescriptor uniqueNo = new UniqueTroopDescriptor(TaleWorlds.Core.Game.Current.NextUniqueTroopSeed); battleAgentOriginArray[rank] = new SPAgentOrigin(_combatant, characterList[rank], this, _combatant.Side, rank, uniqueNo); } if (battleAgentOriginArray.Length < numberToAllocate) { AnyTroopRemainsToBeSupplied = false; } return(battleAgentOriginArray); }
public SPAgentOrigin(SPCombatant combatant, SPSpawnableCharacter character, IEnhancedBattleTestTroopSupplier troopSupplier, BattleSideEnum side, int rank = -1, UniqueTroopDescriptor uniqueNo = default) : base(combatant.Combatant, troopSupplier, side, rank, uniqueNo) { SPCharacter = character; CultureCombatant = combatant; PartyAgentOrigin = new PartyAgentOrigin(combatant.Combatant, character.CharacterObject, rank, uniqueNo); }
public MPAgentOrigin(MPCombatant combatant, MPSpawnableCharacter character, MPTroopSupplier troopSupplier, BattleSideEnum side, int rank = -1, UniqueTroopDescriptor uniqueNo = default) : base(combatant, troopSupplier, side, rank, uniqueNo) { MPCharacter = character; }
public Troop(UniqueTroopDescriptor descriptor, CharacterObject character, bool isAttacker) { Descriptor = descriptor; Character = character; IsAttacker = isAttacker; }
internal static bool Prefix(ref bool __result, ref MapEventSide __instance, ref CharacterObject ____selectedSimulationTroop, ref UniqueTroopDescriptor ____selectedSimulationTroopDescriptor, int damage, DamageTypes damageType, out int troopState, PartyBase strikerParty) { if (strikerParty.MapEvent != null && SimulationModel.IsValidEventType(strikerParty.MapEvent.EventType)) { if (SimulationsPool.TryGetSimulationModel(strikerParty.MapEvent.Id, out var simulationModel)) { SimulationTroopState simulationTroopState = SimulationTroopState.Alive; __result = false; // try to find the attacked troop in our model. Id doesn't exist call vanilla method var troopId = ____selectedSimulationTroop.Id; var troop = simulationModel.Parties[(int)__instance.MissionSide].Troops.Find(t => t.CharacterObject.Id == troopId); if (troop == null) { troopState = (int)simulationTroopState; return(true); } var battleObserver = MapEventSideAccessTools.GetBattleObserver(__instance); var allocatedTroops = MapEventSideAccessTools.GetAllocatedTroops(__instance); // troop is a Hero logic if (____selectedSimulationTroop.IsHero) { __instance.AddHeroDamage(____selectedSimulationTroop.HeroObject, damage); if (____selectedSimulationTroop.HeroObject.IsWounded) { __result = true; simulationTroopState = SimulationTroopState.Wounded; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 0, 1, 0, 0, 0); } } } // regular logic else if (troop.ApplyDamage(damage)) { PartyBase party = allocatedTroops[____selectedSimulationTroopDescriptor].Party; float survivalChance = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(party, ____selectedSimulationTroop, damageType, strikerParty); if (MBRandom.RandomFloat < survivalChance) { __instance.OnTroopWounded(____selectedSimulationTroopDescriptor); simulationTroopState = SimulationTroopState.Wounded; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 0, 1, 0, 0, 0); } SkillLevelingManager.OnSurgeryApplied(party.MobileParty, 1f); } else { __instance.OnTroopKilled(____selectedSimulationTroopDescriptor); simulationTroopState = SimulationTroopState.Kille; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 1, 0, 0, 0, 0); } SkillLevelingManager.OnSurgeryApplied(party.MobileParty, 0.5f); } __result = true; } if (__result) { __instance.RemoveSelectedTroopFromSimulationList(); } troopState = (int)simulationTroopState; return(false); } } troopState = 1; return(true); }
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)); } }