Beispiel #1
0
 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;
 }
Beispiel #2
0
        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);
        }
Beispiel #8
0
        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);
 }
Beispiel #10
0
 public MPAgentOrigin(MPCombatant combatant, MPSpawnableCharacter character, MPTroopSupplier troopSupplier, BattleSideEnum side, int rank = -1, UniqueTroopDescriptor uniqueNo = default)
     : base(combatant, troopSupplier, side, rank, uniqueNo)
 {
     MPCharacter = character;
 }
Beispiel #11
0
 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));
            }
        }