Example #1
0
 private AgentDrivenProperties InitializeHumanAgentStats(
     Agent agent,
     AgentDrivenProperties agentDrivenProperties,
     AgentBuildData agentBuildData)
 {
     MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(agent.Character);
     if (classForCharacter != null)
     {
         this.FillAgentStatsFromData(ref agentDrivenProperties, classForCharacter, agentBuildData?.AgentMissionPeer, agentBuildData?.OwningAgentMissionPeer);
         agentDrivenProperties.SetStat(DrivenProperty.UseRealisticBlocking, MultiplayerOptions.OptionType.UseRealisticBlocking.GetBoolValue() ? 1f : 0.0f);
     }
     agent.BaseHealthLimit = classForCharacter == null ? 100f : (float)classForCharacter.Health;
     agent.HealthLimit     = agent.BaseHealthLimit;
     agent.Health          = agent.HealthLimit;
     return(agentDrivenProperties);
 }
Example #2
0
        public static MultiplayerClassDivisions.MPHeroClass GetMPHeroClassForPeer(
            MissionPeer peer)
        {
            Team team  = peer.Team;
            bool flag1 = team == Mission.Current.AttackerTeam;
            bool flag2 = team == Mission.Current.DefenderTeam;

            if (team == null || !flag1 && !flag2 || peer.SelectedTroopIndex < 0 && peer.ControlledAgent == null)
            {
                return((MultiplayerClassDivisions.MPHeroClass)null);
            }
            if (peer.ControlledAgent != null)
            {
                return(MultiplayerClassDivisions.GetMPHeroClassForCharacter(peer.ControlledAgent.Character));
            }
            return(peer.SelectedTroopIndex >= 0 ? MultiplayerClassDivisions.GetMPHeroClasses(MBObjectManager.Instance.GetObject <BasicCultureObject>(flag1 ? MultiplayerOptions.OptionType.CultureTeam1.GetStrValue() : MultiplayerOptions.OptionType.CultureTeam2.GetStrValue())).ToList <MultiplayerClassDivisions.MPHeroClass>()[peer.SelectedTroopIndex] : (MultiplayerClassDivisions.MPHeroClass)null);
        }
Example #3
0
        private void UpdateTeamPowerBasedOnGold(Team team)
        {
            int num1 = 0;
            int num2 = 0;

            foreach (MissionPeer peer in VirtualPlayer.Peers <MissionPeer>())
            {
                if (peer.Team != null && peer.Team.Side == team.Side)
                {
                    int gold = peer.GetComponent <FlagDominationMissionRepresentative>().Gold;
                    if (gold >= 100)
                    {
                        num2 += gold;
                    }
                    if (peer.ControlledAgent != null && peer.ControlledAgent.IsActive())
                    {
                        MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(peer.ControlledAgent.Character);
                        num2 += classForCharacter.TroopCost;
                    }
                    ++num1;
                }
            }
            int num3 = num1 + (team.Side == BattleSideEnum.Attacker ? MultiplayerOptions.OptionType.NumberOfBotsTeam1.GetIntValue() : MultiplayerOptions.OptionType.NumberOfBotsTeam2.GetIntValue());

            foreach (Agent activeAgent in team.ActiveAgents)
            {
                if (activeAgent.MissionPeer == null)
                {
                    num2 += 300;
                }
            }
            int   num4 = num3 * 300;
            float num5 = Math.Min(1f, num4 == 0 ? 0.0f : (float)num2 / (float)num4);
            Action <BattleSideEnum, float> powerChangedEvent = this.OnTeamPowerChangedEvent;

            if (powerChangedEvent == null)
            {
                return;
            }
            powerChangedEvent(team.Side, num5);
        }
Example #4
0
 public static float CalculateMaximumSpeedMultiplier(Agent agent) => MultiplayerClassDivisions.GetMPHeroClassForCharacter(agent.Character).MovementSpeedMultiplier;
Example #5
0
        private void UpdateHumanAgentStats(Agent agent, AgentDrivenProperties agentDrivenProperties)
        {
            MPPerkObject.MPPerkHandler perkHandler = MPPerkObject.GetPerkHandler(agent);
            BasicCharacterObject       character   = agent.Character;
            MissionEquipment           equipment   = agent.Equipment;
            float          num1 = equipment.GetTotalWeightOfWeapons() * (float)(1.0 + (perkHandler != null ? (double)perkHandler.GetEncumbrance(true) : 0.0));
            EquipmentIndex wieldedItemIndex1 = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand);
            EquipmentIndex wieldedItemIndex2 = agent.GetWieldedItemIndex(Agent.HandIndex.OffHand);

            if (wieldedItemIndex1 != EquipmentIndex.None)
            {
                ItemObject      itemObject       = equipment[wieldedItemIndex1].Item;
                WeaponComponent weaponComponent  = itemObject.WeaponComponent;
                float           realWeaponLength = weaponComponent.PrimaryWeapon.GetRealWeaponLength();
                float           num2             = (weaponComponent.GetItemType() == ItemObject.ItemTypeEnum.Bow ? 4f : 1.5f) * itemObject.Weight * MathF.Sqrt(realWeaponLength) * (float)(1.0 + (perkHandler != null ? (double)perkHandler.GetEncumbrance(false) : 0.0));
                num1 += num2;
            }
            if (wieldedItemIndex2 != EquipmentIndex.None)
            {
                float num2 = 1.5f * equipment[wieldedItemIndex2].Item.Weight * (float)(1.0 + (perkHandler != null ? (double)perkHandler.GetEncumbrance(false) : 0.0));
                num1 += num2;
            }
            agentDrivenProperties.WeaponsEncumbrance = num1;
            EquipmentIndex      wieldedItemIndex3   = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand);
            WeaponComponentData weaponComponentData = wieldedItemIndex3 != EquipmentIndex.None ? equipment[wieldedItemIndex3].CurrentUsageItem : (WeaponComponentData)null;
            ItemObject          primaryItem         = wieldedItemIndex3 != EquipmentIndex.None ? equipment[wieldedItemIndex3].Item : (ItemObject)null;
            EquipmentIndex      wieldedItemIndex4   = agent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
            WeaponComponentData secondaryItem       = wieldedItemIndex4 != EquipmentIndex.None ? equipment[wieldedItemIndex4].CurrentUsageItem : (WeaponComponentData)null;
            float inaccuracy;

            agentDrivenProperties.LongestRangedWeaponSlotIndex       = (float)equipment.GetLongestRangedWeaponWithAimingError(out inaccuracy, agent);
            agentDrivenProperties.LongestRangedWeaponInaccuracy      = inaccuracy;
            agentDrivenProperties.SwingSpeedMultiplier               = (float)(0.930000007152557 + 0.000699999975040555 * (double)this.GetSkillValueForItem(character, primaryItem));
            agentDrivenProperties.ThrustOrRangedReadySpeedMultiplier = agentDrivenProperties.SwingSpeedMultiplier;
            agentDrivenProperties.HandlingMultiplier = 1f;
            agentDrivenProperties.ShieldBashStunDurationMultiplier = 1f;
            agentDrivenProperties.KickStunDurationMultiplier       = 1f;
            agentDrivenProperties.ReloadSpeed = (float)(0.930000007152557 + 0.000699999975040555 * (double)this.GetSkillValueForItem(character, primaryItem));
            agentDrivenProperties.ReloadMovementPenaltyFactor = 1f;
            agentDrivenProperties.WeaponInaccuracy            = 0.0f;
            MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(agent.Character);
            agentDrivenProperties.MaxSpeedMultiplier = (float)(1.04999995231628 * ((double)classForCharacter.MovementSpeedMultiplier * (100.0 / (100.0 + (double)num1))));
            int  skillValue = character.GetSkillValue(DefaultSkills.Riding);
            bool flag1      = false;
            bool flag2      = false;

            if (weaponComponentData != null)
            {
                int weaponSkill = character.GetSkillValue(weaponComponentData.RelevantSkill);
                if (weaponSkill > 0 && weaponComponentData.IsRangedWeapon && perkHandler != null)
                {
                    weaponSkill = MathF.Ceiling((float)weaponSkill * (perkHandler.GetRangedAccuracy() + 1f));
                }
                int thrustSpeed = weaponComponentData.ThrustSpeed;
                agentDrivenProperties.WeaponInaccuracy = this.GetWeaponInaccuracy(agent, weaponComponentData, weaponSkill);
                if (weaponComponentData.IsRangedWeapon)
                {
                    agentDrivenProperties.WeaponMaxMovementAccuracyPenalty = (float)(500 - weaponSkill) * 0.00025f;
                    agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty = (float)(500 - weaponSkill) * 0.0002f;
                    if (agent.HasMount)
                    {
                        agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= Math.Max(1f, (float)(700 - weaponSkill - skillValue) * (3f / 1000f));
                        agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= Math.Max(1f, (float)(700 - weaponSkill - skillValue) * 0.0033f);
                    }
                    else if (weaponComponentData.RelevantSkill == DefaultSkills.Bow)
                    {
                        agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= 4.5f / MBMath.Lerp(0.75f, 2f, (float)(((double)thrustSpeed - 60.0) / 75.0));
                        agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= 6f;
                    }
                    else if (weaponComponentData.RelevantSkill == DefaultSkills.Crossbow)
                    {
                        agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= 1.2f;
                        agentDrivenProperties.WeaponMaxMovementAccuracyPenalty *= 2.5f;
                    }
                    else if (weaponComponentData.RelevantSkill == DefaultSkills.Throwing)
                    {
                        agentDrivenProperties.WeaponMaxUnsteadyAccuracyPenalty *= 3.5f * MBMath.Lerp(1.5f, 0.8f, (float)(((double)thrustSpeed - 89.0) / 13.0));
                    }
                    if (weaponComponentData.WeaponClass == WeaponClass.Bow)
                    {
                        flag1 = true;
                        agentDrivenProperties.WeaponBestAccuracyWaitTime = (float)(0.300000011920929 + (95.75 - (double)thrustSpeed) * 0.00499999988824129);
                        agentDrivenProperties.WeaponUnsteadyBeginTime    = (float)(0.100000001490116 + (double)weaponSkill * 0.00999999977648258 * (double)MBMath.Lerp(1f, 2f, (float)(((double)thrustSpeed - 60.0) / 75.0)));
                        if (agent.IsAIControlled)
                        {
                            agentDrivenProperties.WeaponUnsteadyBeginTime *= 4f;
                        }
                        agentDrivenProperties.WeaponUnsteadyEndTime = 2f + agentDrivenProperties.WeaponUnsteadyBeginTime;
                        agentDrivenProperties.WeaponRotationalAccuracyPenaltyInRadians = 0.1f;
                    }
                    else if (weaponComponentData.WeaponClass == WeaponClass.Javelin || weaponComponentData.WeaponClass == WeaponClass.ThrowingAxe || weaponComponentData.WeaponClass == WeaponClass.ThrowingKnife)
                    {
                        agentDrivenProperties.WeaponBestAccuracyWaitTime = (float)(0.400000005960464 + (89.0 - (double)thrustSpeed) * 0.0299999993294477);
                        agentDrivenProperties.WeaponUnsteadyBeginTime    = (float)(2.5 + (double)weaponSkill * 0.00999999977648258);
                        agentDrivenProperties.WeaponUnsteadyEndTime      = 10f + agentDrivenProperties.WeaponUnsteadyBeginTime;
                        agentDrivenProperties.WeaponRotationalAccuracyPenaltyInRadians = 0.025f;
                    }
                    else
                    {
                        agentDrivenProperties.WeaponBestAccuracyWaitTime = 0.1f;
                        agentDrivenProperties.WeaponUnsteadyBeginTime    = 0.0f;
                        agentDrivenProperties.WeaponUnsteadyEndTime      = 0.0f;
                        agentDrivenProperties.WeaponRotationalAccuracyPenaltyInRadians = 0.1f;
                    }
                }
                else if (weaponComponentData.WeaponFlags.HasAllFlags <WeaponFlags>(WeaponFlags.WideGrip))
                {
                    flag2 = true;
                    agentDrivenProperties.WeaponUnsteadyBeginTime = (float)(1.0 + (double)weaponSkill * 0.00499999988824129);
                    agentDrivenProperties.WeaponUnsteadyEndTime   = (float)(3.0 + (double)weaponSkill * 0.00999999977648258);
                }
            }
            agentDrivenProperties.AttributeShieldMissileCollisionBodySizeAdder = 0.3f;
            Agent mountAgent = agent.MountAgent;
            float num3       = mountAgent != null?mountAgent.GetAgentDrivenPropertyValue(DrivenProperty.AttributeRiding) : 1f;

            agentDrivenProperties.AttributeRiding                    = (float)skillValue * num3;
            agentDrivenProperties.AttributeHorseArchery              = Game.Current.BasicModels.StrikeMagnitudeModel.CalculateHorseArcheryFactor(character);
            agentDrivenProperties.BipedalRangedReadySpeedMultiplier  = ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.BipedalRangedReadySpeedMultiplier);
            agentDrivenProperties.BipedalRangedReloadSpeedMultiplier = ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.BipedalRangedReloadSpeedMultiplier);
            foreach (DrivenPropertyBonusAgentComponent bonusAgentComponent in agent.Components.OfType <DrivenPropertyBonusAgentComponent>())
            {
                if (!MBMath.IsBetween((int)bonusAgentComponent.DrivenProperty, 0, 56))
                {
                    float num2 = agentDrivenProperties.GetStat(bonusAgentComponent.DrivenProperty) + bonusAgentComponent.DrivenPropertyBonus;
                    agentDrivenProperties.SetStat(bonusAgentComponent.DrivenProperty, num2);
                }
            }
            if (perkHandler != null)
            {
                for (int index = 56; index < 85; ++index)
                {
                    DrivenProperty drivenProperty = (DrivenProperty)index;
                    if (((drivenProperty == DrivenProperty.WeaponUnsteadyBeginTime ? 0 : (drivenProperty != DrivenProperty.WeaponUnsteadyEndTime ? 1 : 0)) | (flag1 ? 1 : 0) | (flag2 ? 1 : 0)) != 0 && drivenProperty != DrivenProperty.WeaponRotationalAccuracyPenaltyInRadians | flag1)
                    {
                        float stat = agentDrivenProperties.GetStat(drivenProperty);
                        agentDrivenProperties.SetStat(drivenProperty, stat + perkHandler.GetDrivenPropertyBonus(drivenProperty, stat));
                    }
                }
            }
            this.SetAiRelatedProperties(agent, agentDrivenProperties, weaponComponentData, secondaryItem);
        }
Example #6
0
 public override void OnAgentRemoved(
     Agent affectedAgent,
     Agent affectorAgent,
     AgentState agentState,
     KillingBlow blow)
 {
     base.OnAgentRemoved(affectedAgent, affectorAgent, agentState, blow);
     if (this.UseGold() && affectorAgent != null && (affectedAgent != null && affectedAgent.IsHuman) && (blow.DamageType != DamageTypes.Invalid && (agentState == AgentState.Unconscious || agentState == AgentState.Killed)))
     {
         Agent.Hitter assistingHitter = affectedAgent.GetAssistingHitter(affectorAgent.MissionPeer);
         MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(affectedAgent.Character);
         if (affectorAgent.MissionPeer != null && affectorAgent.MissionPeer.Representative is FlagDominationMissionRepresentative representative10)
         {
             int gainsFromKillData = representative10.GetGoldGainsFromKillData(MPPerkObject.GetPerkHandler(affectorAgent.MissionPeer), MPPerkObject.GetPerkHandler(assistingHitter?.HitterPeer), classForCharacter, false);
             if (gainsFromKillData > 0)
             {
                 this.ChangeCurrentGoldForPeer(affectorAgent.MissionPeer, representative10.Gold + gainsFromKillData);
             }
         }
         if (assistingHitter?.HitterPeer != null && !assistingHitter.IsFriendlyHit && assistingHitter.HitterPeer.Representative is FlagDominationMissionRepresentative representative11)
         {
             int gainsFromKillData = representative11.GetGoldGainsFromKillData(MPPerkObject.GetPerkHandler(affectorAgent.MissionPeer), MPPerkObject.GetPerkHandler(assistingHitter.HitterPeer), classForCharacter, false);
             if (gainsFromKillData > 0)
             {
                 this.ChangeCurrentGoldForPeer(assistingHitter.HitterPeer, representative11.Gold + gainsFromKillData);
             }
         }
         if (affectedAgent.MissionPeer?.Team != null)
         {
             IEnumerable <(MissionPeer, int)> goldRewardsOnDeath = MPPerkObject.GetPerkHandler(affectedAgent.MissionPeer)?.GetTeamGoldRewardsOnDeath();
             if (goldRewardsOnDeath != null)
             {
                 foreach ((MissionPeer peer6, int baseAmount6) in goldRewardsOnDeath)
                 {
                     if (baseAmount6 > 0 && peer6?.Representative is FlagDominationMissionRepresentative representative12)
                     {
                         int local_11 = representative12.GetGoldGainsFromAllyDeathReward(baseAmount6);
                         if (local_11 > 0)
                         {
                             this.ChangeCurrentGoldForPeer(peer6, representative12.Gold + local_11);
                         }
                     }
                 }
             }
         }
     }
     if (affectedAgent.IsPlayerControlled)
     {
         affectedAgent.MissionPeer.GetComponent <FlagDominationMissionRepresentative>().UpdateSelectedClassServer((Agent)null);
     }
     else
     {
         if (MultiplayerOptions.OptionType.NumberOfBotsPerFormation.GetIntValue() <= 0 || this.WarmupComponent != null && this.WarmupComponent.IsInWarmup || (affectedAgent.IsMount || affectedAgent.OwningAgentMissionPeer == null || (affectedAgent.Formation == null || affectedAgent.Formation.CountOfUnits != 1)))
         {
             return;
         }
         if (!GameNetwork.IsDedicatedServer)
         {
             MatrixFrame cameraFrame = Mission.Current.GetCameraFrame();
             Vec3        position    = cameraFrame.origin + cameraFrame.rotation.u;
             MBSoundEvent.PlaySound(SoundEvent.GetEventIdFromString("event:/alerts/report/squad_wiped"), position);
         }
         GameNetwork.BeginBroadcastModuleEvent();
         GameNetwork.WriteMessage((GameNetworkMessage) new FormationWipedMessage());
         GameNetwork.EndBroadcastModuleEvent(GameNetwork.EventBroadcastFlags.ExcludeOtherTeamPlayers, affectedAgent.OwningAgentMissionPeer.GetNetworkPeer());
     }
 }
Example #7
0
 public override int GetScoreForAssist(Agent killedAgent) => (int)((double)MultiplayerClassDivisions.GetMPHeroClassForCharacter(killedAgent.Character).TroopCost * 0.5);
Example #8
0
 public override int GetScoreForKill(Agent killedAgent) => MultiplayerClassDivisions.GetMPHeroClassForCharacter(killedAgent.Character).TroopCost;
Example #9
0
        public override void OnAgentRemoved(
            Agent affectedAgent,
            Agent affectorAgent,
            AgentState agentState,
            KillingBlow blow)
        {
            if (blow.DamageType == DamageTypes.Invalid || agentState != AgentState.Unconscious && agentState != AgentState.Killed || !affectedAgent.IsHuman)
            {
                return;
            }
            if (affectorAgent != null && affectorAgent.IsEnemyOf(affectedAgent))
            {
                this._missionScoreboardComponent.ChangeTeamScore(affectorAgent.Team, this.GetScoreForKill(affectedAgent));
            }
            else
            {
                this._missionScoreboardComponent.ChangeTeamScore(affectedAgent.Team, -this.GetScoreForKill(affectedAgent));
            }
            MissionPeer missionPeer = affectedAgent.MissionPeer;

            if (missionPeer != null)
            {
                int num1 = 100;
                if (affectorAgent != affectedAgent)
                {
                    List <MissionPeer>[] missionPeerListArray = new List <MissionPeer> [2];
                    for (int index = 0; index < missionPeerListArray.Length; ++index)
                    {
                        missionPeerListArray[index] = new List <MissionPeer>();
                    }
                    foreach (NetworkCommunicator networkPeer in GameNetwork.NetworkPeers)
                    {
                        MissionPeer component = networkPeer.GetComponent <MissionPeer>();
                        if (component != null && component.Team != null && component.Team.Side != BattleSideEnum.None)
                        {
                            missionPeerListArray[(int)component.Team.Side].Add(component);
                        }
                    }
                    int            num2           = missionPeerListArray[1].Count - missionPeerListArray[0].Count;
                    BattleSideEnum battleSideEnum = num2 == 0 ? BattleSideEnum.None : (num2 < 0 ? BattleSideEnum.Attacker : BattleSideEnum.Defender);
                    if (battleSideEnum != BattleSideEnum.None && battleSideEnum == missionPeer.Team.Side)
                    {
                        int num3  = Math.Abs(num2);
                        int count = missionPeerListArray[(int)battleSideEnum].Count;
                        if (count > 0)
                        {
                            int num4 = num1 * num3 / 10 / count * 10;
                            num1 += num4;
                        }
                    }
                }
                this.ChangeCurrentGoldForPeer(missionPeer, missionPeer.Representative.Gold + num1);
            }
            MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(affectedAgent.Character);
            Agent.Hitter assistingHitter = affectedAgent.GetAssistingHitter(affectorAgent?.MissionPeer);
            if (affectorAgent?.MissionPeer != null && affectorAgent != affectedAgent && !affectorAgent.IsFriendOf(affectedAgent))
            {
                TeamDeathmatchMissionRepresentative representative = affectorAgent.MissionPeer.Representative as TeamDeathmatchMissionRepresentative;
                int dataAndUpdateFlags = representative.GetGoldGainsFromKillDataAndUpdateFlags(MPPerkObject.GetPerkHandler(affectorAgent.MissionPeer), MPPerkObject.GetPerkHandler(assistingHitter?.HitterPeer), classForCharacter, false, blow.IsMissile);
                this.ChangeCurrentGoldForPeer(affectorAgent.MissionPeer, representative.Gold + dataAndUpdateFlags);
            }
            if (assistingHitter?.HitterPeer != null && !assistingHitter.IsFriendlyHit)
            {
                TeamDeathmatchMissionRepresentative representative = assistingHitter.HitterPeer.Representative as TeamDeathmatchMissionRepresentative;
                int dataAndUpdateFlags = representative.GetGoldGainsFromKillDataAndUpdateFlags(MPPerkObject.GetPerkHandler(affectorAgent?.MissionPeer), MPPerkObject.GetPerkHandler(assistingHitter.HitterPeer), classForCharacter, true, blow.IsMissile);
                this.ChangeCurrentGoldForPeer(assistingHitter.HitterPeer, representative.Gold + dataAndUpdateFlags);
            }
            if (missionPeer?.Team == null)
            {
                return;
            }
            IEnumerable <(MissionPeer, int)> goldRewardsOnDeath = MPPerkObject.GetPerkHandler(missionPeer)?.GetTeamGoldRewardsOnDeath();

            if (goldRewardsOnDeath == null)
            {
                return;
            }
            foreach ((MissionPeer peer, int baseAmount) in goldRewardsOnDeath)
            {
                if (peer?.Representative is TeamDeathmatchMissionRepresentative representative1)
                {
                    int local_21 = representative1.GetGoldGainsFromAllyDeathReward(baseAmount);
                    if (local_21 > 0)
                    {
                        this.ChangeCurrentGoldForPeer(peer, representative1.Gold + local_21);
                    }
                }
            }
        }
Example #10
0
        public void SpawnAgentVisualsForPeer(
            MissionPeer missionPeer,
            AgentBuildData buildData,
            int selectedEquipmentSetIndex = -1,
            bool isBot          = false,
            int totalTroopCount = 0)
        {
            NetworkCommunicator myPeer = GameNetwork.MyPeer;

            if (myPeer != null)
            {
                myPeer.GetComponent <MissionPeer>();
            }
            if (buildData.AgentVisualsIndex == 0)
            {
                missionPeer.ClearAllVisuals();
            }
            missionPeer.ClearVisuals(buildData.AgentVisualsIndex);
            Equipment        overridenSpawnEquipment = buildData.AgentOverridenSpawnEquipment;
            ItemObject       mountItem           = overridenSpawnEquipment[10].Item;
            MatrixFrame      pointFrameForPlayer = this._spawnFrameSelectionHelper.GetSpawnPointFrameForPlayer(missionPeer.Peer, missionPeer.Team.Side, buildData.AgentVisualsIndex, totalTroopCount, mountItem != null);
            ActionIndexCache actionIndexCache1   = mountItem == null ? SpawningBehaviourBase.PoseActionInfantry : SpawningBehaviourBase.PoseActionCavalry;

            MultiplayerClassDivisions.MPHeroClass classForCharacter = MultiplayerClassDivisions.GetMPHeroClassForCharacter(buildData.AgentCharacter);
            IReadOnlyList <MPPerkObject>          selectedPerks     = missionPeer.SelectedPerks;
            float        parameter    = (float)(0.100000001490116 + (double)MBRandom.RandomFloat * 0.800000011920929);
            IAgentVisual mountVisuals = (IAgentVisual)null;

            if (mountItem != null)
            {
                Monster          monster = mountItem.HorseComponent.Monster;
                AgentVisualsData data    = new AgentVisualsData().Equipment(overridenSpawnEquipment).Scale(mountItem.ScaleFactor).Frame(MatrixFrame.Identity).ActionSet(MBGlobals.GetActionSet(monster.ActionSetCode)).Scene(Mission.Current.Scene).Monster(monster).PrepareImmediately(false).MountCreationKey(MountCreationKey.GetRandomMountKey(mountItem, MBRandom.RandomInt()));
                mountVisuals = Mission.Current.AgentVisualCreator.Create(data, "Agent " + buildData.AgentCharacter.StringId + " mount", true);
                MatrixFrame frame = pointFrameForPlayer;
                frame.rotation.ApplyScaleLocal(data.ScaleData);
                ActionIndexCache actionName = ActionIndexCache.act_none;
                foreach (MPPerkObject mpPerkObject in (IEnumerable <MPPerkObject>)selectedPerks)
                {
                    if (!isBot && mpPerkObject.HeroMountIdleAnimOverride != null)
                    {
                        actionName = ActionIndexCache.Create(mpPerkObject.HeroMountIdleAnimOverride);
                        break;
                    }
                    if (isBot && mpPerkObject.TroopMountIdleAnimOverride != null)
                    {
                        actionName = ActionIndexCache.Create(mpPerkObject.TroopMountIdleAnimOverride);
                        break;
                    }
                }
                if (actionName == ActionIndexCache.act_none)
                {
                    if (mountItem.StringId == "mp_aserai_camel")
                    {
                        Debug.Print("Client is spawning a camel for without mountCustomAction from the perk.", debugFilter: 17179869184UL);
                        actionName = isBot ? ActionIndexCache.Create("act_camel_idle_1") : ActionIndexCache.Create("act_hero_mount_idle_camel");
                    }
                    else
                    {
                        if (!isBot && !string.IsNullOrEmpty(classForCharacter.HeroMountIdleAnim))
                        {
                            actionName = ActionIndexCache.Create(classForCharacter.HeroMountIdleAnim);
                        }
                        if (isBot && !string.IsNullOrEmpty(classForCharacter.TroopMountIdleAnim))
                        {
                            actionName = ActionIndexCache.Create(classForCharacter.TroopMountIdleAnim);
                        }
                    }
                }
                if (actionName != ActionIndexCache.act_none)
                {
                    mountVisuals.SetAction(actionName);
                    mountVisuals.GetVisuals().GetSkeleton().SetAnimationParameterAtChannel(0, parameter);
                    mountVisuals.GetVisuals().GetSkeleton().TickAnimationsAndForceUpdate(0.1f, frame, true);
                }
                mountVisuals.GetVisuals().GetEntity().SetFrame(ref frame);
            }
            ActionIndexCache actionIndexCache2 = actionIndexCache1;

            if (mountVisuals != null)
            {
                actionIndexCache2 = mountVisuals.GetVisuals().GetSkeleton().GetActionAtChannel(0);
            }
            else
            {
                foreach (MPPerkObject mpPerkObject in (IEnumerable <MPPerkObject>)selectedPerks)
                {
                    if (!isBot && mpPerkObject.HeroIdleAnimOverride != null)
                    {
                        actionIndexCache2 = ActionIndexCache.Create(mpPerkObject.HeroIdleAnimOverride);
                        break;
                    }
                    if (isBot && mpPerkObject.TroopIdleAnimOverride != null)
                    {
                        actionIndexCache2 = ActionIndexCache.Create(mpPerkObject.TroopIdleAnimOverride);
                        break;
                    }
                }
                if (actionIndexCache2 == actionIndexCache1)
                {
                    if (!isBot && !string.IsNullOrEmpty(classForCharacter.HeroIdleAnim))
                    {
                        actionIndexCache2 = ActionIndexCache.Create(classForCharacter.HeroIdleAnim);
                    }
                    if (isBot && !string.IsNullOrEmpty(classForCharacter.TroopIdleAnim))
                    {
                        actionIndexCache2 = ActionIndexCache.Create(classForCharacter.TroopIdleAnim);
                    }
                }
            }
            IAgentVisual agentVisuals = Mission.Current.AgentVisualCreator.Create(new AgentVisualsData().Equipment(overridenSpawnEquipment).BodyProperties(buildData.AgentBodyProperties).Frame(pointFrameForPlayer).ActionSet(MBGlobals.PlayerMaleActionSet).Scene(Mission.Current.Scene).Monster(Game.Current.HumanMonster).PrepareImmediately(false).UseMorphAnims(true).SkeletonType(buildData.AgentIsFemale ? SkeletonType.Female : SkeletonType.Male).ClothColor1(buildData.AgentClothingColor1).ClothColor2(buildData.AgentClothingColor2).AddColorRandomness((uint)buildData.AgentVisualsIndex > 0U).ActionCode(actionIndexCache2), "Mission::SpawnAgentVisuals", true);

            agentVisuals.SetAction(actionIndexCache2);
            agentVisuals.GetVisuals().GetSkeleton().SetAnimationParameterAtChannel(0, parameter);
            agentVisuals.GetVisuals().GetSkeleton().TickAnimationsAndForceUpdate(0.1f, pointFrameForPlayer, true);
            agentVisuals.GetVisuals().SetFrame(ref pointFrameForPlayer);
            agentVisuals.SetCharacterObjectID(buildData.AgentCharacter.StringId);
            EquipmentIndex mainHandWeaponIndex;
            EquipmentIndex offHandWeaponIndex;
            bool           isMainHandNotUsableWithOneHand;

            overridenSpawnEquipment.GetInitialWeaponIndicesToEquip(out mainHandWeaponIndex, out offHandWeaponIndex, out isMainHandNotUsableWithOneHand);
            if (isMainHandNotUsableWithOneHand)
            {
                offHandWeaponIndex = EquipmentIndex.None;
            }
            agentVisuals.GetVisuals().SetWieldedWeaponIndices((int)mainHandWeaponIndex, (int)offHandWeaponIndex);
            PeerVisualsHolder visualsHolder = new PeerVisualsHolder(missionPeer, buildData.AgentVisualsIndex, agentVisuals, mountVisuals);

            missionPeer.OnVisualsSpawned(visualsHolder, visualsHolder.VisualsIndex);
            if (buildData.AgentVisualsIndex == 0)
            {
                missionPeer.HasSpawnedAgentVisuals   = true;
                missionPeer.EquipmentUpdatingExpired = false;
            }
            if (!missionPeer.IsMine || buildData.AgentVisualsIndex != 0)
            {
                return;
            }
            Action agentVisualSpawned = this.OnMyAgentVisualSpawned;

            if (agentVisualSpawned == null)
            {
                return;
            }
            agentVisualSpawned();
        }