protected BodyProperties GetBodyProperties(
            MissionPeer missionPeer,
            BasicCultureObject cultureLimit)
        {
            NetworkCommunicator networkPeer = missionPeer.GetNetworkPeer();

            if (networkPeer != null)
            {
                return(networkPeer.PlayerConnectionInfo.GetParameter <PlayerData>("PlayerData").BodyProperties);
            }
            Team team = missionPeer.Team;
            BasicCharacterObject troopCharacter = MultiplayerClassDivisions.GetMPHeroClasses(cultureLimit).ToList <MultiplayerClassDivisions.MPHeroClass>().GetRandomElement <MultiplayerClassDivisions.MPHeroClass>().TroopCharacter;
            MatrixFrame          spawnFrame     = this.SpawnComponent.GetSpawnFrame(team, troopCharacter.HasMount(), true);
            AgentBuildData       agentBuildData = new AgentBuildData(troopCharacter);

            agentBuildData.Team(team);
            agentBuildData.InitialFrame(spawnFrame);
            agentBuildData.TroopOrigin((IAgentOriginBase) new BasicBattleAgentOrigin(troopCharacter));
            agentBuildData.EquipmentSeed(this.MissionLobbyComponent.GetRandomFaceSeedForCharacter(troopCharacter));
            agentBuildData.ClothingColor1(team.Side == BattleSideEnum.Attacker ? cultureLimit.Color : cultureLimit.ClothAlternativeColor);
            agentBuildData.ClothingColor2(team.Side == BattleSideEnum.Attacker ? cultureLimit.Color2 : cultureLimit.ClothAlternativeColor2);
            agentBuildData.IsFemale(troopCharacter.IsFemale);
            agentBuildData.Equipment(Equipment.GetRandomEquipmentElements(troopCharacter, !(Game.Current.GameType is MultiplayerGame), seed: agentBuildData.AgentEquipmentSeed));
            agentBuildData.BodyProperties(BodyProperties.GetRandomBodyProperties(agentBuildData.AgentIsFemale, troopCharacter.GetBodyPropertiesMin(), troopCharacter.GetBodyPropertiesMax(), (int)agentBuildData.AgentOverridenSpawnEquipment.HairCoverType, agentBuildData.AgentEquipmentSeed, troopCharacter.HairTags, troopCharacter.BeardTags, troopCharacter.TattooTags));
            return(agentBuildData.AgentBodyProperties);
        }
        protected void SpawnBot(Team agentTeam, BasicCultureObject cultureLimit)
        {
            BasicCharacterObject troopCharacter = MultiplayerClassDivisions.GetMPHeroClasses(cultureLimit).ToList <MultiplayerClassDivisions.MPHeroClass>().GetRandomElement <MultiplayerClassDivisions.MPHeroClass>().TroopCharacter;
            MatrixFrame          spawnFrame     = this.SpawnComponent.GetSpawnFrame(agentTeam, troopCharacter.HasMount(), true);
            AgentBuildData       agentBuildData = new AgentBuildData(troopCharacter);

            agentBuildData.Team(agentTeam);
            agentBuildData.InitialFrame(spawnFrame);
            agentBuildData.TroopOrigin((IAgentOriginBase) new BasicBattleAgentOrigin(troopCharacter));
            agentBuildData.EquipmentSeed(this.MissionLobbyComponent.GetRandomFaceSeedForCharacter(troopCharacter));
            agentBuildData.ClothingColor1(agentTeam.Side == BattleSideEnum.Attacker ? cultureLimit.Color : cultureLimit.ClothAlternativeColor);
            agentBuildData.ClothingColor2(agentTeam.Side == BattleSideEnum.Attacker ? cultureLimit.Color2 : cultureLimit.ClothAlternativeColor2);
            agentBuildData.IsFemale(troopCharacter.IsFemale);
            agentBuildData.Equipment(Equipment.GetRandomEquipmentElements(troopCharacter, !(Game.Current.GameType is MultiplayerGame), seed: agentBuildData.AgentEquipmentSeed));
            agentBuildData.BodyProperties(BodyProperties.GetRandomBodyProperties(agentBuildData.AgentIsFemale, troopCharacter.GetBodyPropertiesMin(), troopCharacter.GetBodyPropertiesMax(), (int)agentBuildData.AgentOverridenSpawnEquipment.HairCoverType, agentBuildData.AgentEquipmentSeed, troopCharacter.HairTags, troopCharacter.BeardTags, troopCharacter.TattooTags));
            Agent agent = this.Mission.SpawnAgent(agentBuildData);

            agent.AddComponent((AgentComponent) new AgentAIStateFlagComponent(agent));
            agent.SetWatchState(AgentAIStateFlagComponent.WatchState.Alarmed);
        }
        protected override void SpawnAgents()
        {
            BasicCultureObject cultureLimit1 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam1.GetStrValue());
            BasicCultureObject cultureLimit2 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam2.GetStrValue());

            foreach (MissionPeer peer in VirtualPlayer.Peers <MissionPeer>())
            {
                if (peer.GetNetworkPeer().IsSynchronized&& peer.ControlledAgent == null && (!peer.HasSpawnedAgentVisuals && peer.Team != null) && (peer.Team != this.Mission.SpectatorTeam && peer.SpawnTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission))))
                {
                    IAgentVisual       agentVisualForPeer = peer.GetAgentVisualForPeer(0);
                    BasicCultureObject basicCultureObject = peer.Team.Side == BattleSideEnum.Attacker ? cultureLimit1 : cultureLimit2;
                    int num = peer.SelectedTroopIndex;
                    IEnumerable <MultiplayerClassDivisions.MPHeroClass> mpHeroClasses = MultiplayerClassDivisions.GetMPHeroClasses(basicCultureObject);
                    MultiplayerClassDivisions.MPHeroClass mpHeroClass = num < 0 ? (MultiplayerClassDivisions.MPHeroClass)null : mpHeroClasses.ElementAt <MultiplayerClassDivisions.MPHeroClass>(num);
                    if (mpHeroClass == null && num < 0)
                    {
                        mpHeroClass = mpHeroClasses.First <MultiplayerClassDivisions.MPHeroClass>();
                        num         = 0;
                    }
                    BasicCharacterObject heroCharacter = mpHeroClass.HeroCharacter;
                    Equipment            equipment     = heroCharacter.Equipment.Clone();
                    IEnumerable <(EquipmentIndex, EquipmentElement)> alternativeEquipments = MPPerkObject.GetOnSpawnPerkHandler(peer)?.GetAlternativeEquipments(true);
                    if (alternativeEquipments != null)
                    {
                        foreach ((EquipmentIndex, EquipmentElement)tuple in alternativeEquipments)
                        {
                            equipment[tuple.Item1] = tuple.Item2;
                        }
                    }
                    AgentBuildData agentBuildData = new AgentBuildData(heroCharacter);
                    agentBuildData.MissionPeer(peer);
                    agentBuildData.Equipment(equipment);
                    agentBuildData.Team(peer.Team);
                    MatrixFrame frame;
                    if (agentVisualForPeer == null)
                    {
                        frame = this.SpawnComponent.GetSpawnFrame(peer.Team, heroCharacter.Equipment.Horse.Item != null);
                    }
                    else
                    {
                        frame = agentVisualForPeer.GetFrame();
                        frame.rotation.MakeUnit();
                    }
                    agentBuildData.InitialFrame(frame);
                    agentBuildData.IsFemale(peer.Peer.IsFemale);
                    BodyProperties bodyProperties = this.GetBodyProperties(peer, basicCultureObject);
                    agentBuildData.BodyProperties(bodyProperties);
                    agentBuildData.VisualsIndex(0);
                    agentBuildData.ClothingColor1(peer.Team == this.Mission.AttackerTeam ? basicCultureObject.Color : basicCultureObject.ClothAlternativeColor);
                    agentBuildData.ClothingColor2(peer.Team == this.Mission.AttackerTeam ? basicCultureObject.Color2 : basicCultureObject.ClothAlternativeColor2);
                    agentBuildData.TroopOrigin((IAgentOriginBase) new BasicBattleAgentOrigin(heroCharacter));
                    NetworkCommunicator networkPeer = peer.GetNetworkPeer();
                    if (this.GameMode.ShouldSpawnVisualsForServer(networkPeer))
                    {
                        this.AgentVisualSpawnComponent.SpawnAgentVisualsForPeer(peer, agentBuildData, num);
                    }
                    this.GameMode.HandleAgentVisualSpawning(networkPeer, agentBuildData);
                }
            }
            if (this.Mission.AttackerTeam != null)
            {
                int num = 0;
                foreach (Agent activeAgent in this.Mission.AttackerTeam.ActiveAgents)
                {
                    if (activeAgent.Character != null && activeAgent.MissionPeer == null)
                    {
                        ++num;
                    }
                }
                if (num < MultiplayerOptions.OptionType.NumberOfBotsTeam1.GetIntValue())
                {
                    this.SpawnBot(this.Mission.AttackerTeam, cultureLimit1);
                }
            }
            if (this.Mission.DefenderTeam == null)
            {
                return;
            }
            int num1 = 0;

            foreach (Agent activeAgent in this.Mission.DefenderTeam.ActiveAgents)
            {
                if (activeAgent.Character != null && activeAgent.MissionPeer == null)
                {
                    ++num1;
                }
            }
            if (num1 >= MultiplayerOptions.OptionType.NumberOfBotsTeam2.GetIntValue())
            {
                return;
            }
            this.SpawnBot(this.Mission.DefenderTeam, cultureLimit2);
        }
        public virtual void OnTick(float dt)
        {
            foreach (MissionPeer peer in VirtualPlayer.Peers <MissionPeer>())
            {
                if (peer.GetNetworkPeer().IsSynchronized&& peer.ControlledAgent == null && (peer.HasSpawnedAgentVisuals && !this.CanUpdateSpawnEquipment(peer)))
                {
                    BasicCultureObject basicCultureObject1 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam1.GetStrValue());
                    BasicCultureObject basicCultureObject2 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam2.GetStrValue());
                    MultiplayerClassDivisions.MPHeroClass heroClassForPeer = MultiplayerClassDivisions.GetMPHeroClassForPeer(peer);
                    MPPerkObject.MPOnSpawnPerkHandler     spawnPerkHandler = MPPerkObject.GetOnSpawnPerkHandler(peer);
                    int  num1  = 0;
                    bool flag1 = false;
                    if (MultiplayerOptions.OptionType.NumberOfBotsPerFormation.GetIntValue() > 0 && (this.GameMode.WarmupComponent == null || !this.GameMode.WarmupComponent.IsInWarmup))
                    {
                        num1 = MPPerkObject.GetTroopCount(heroClassForPeer, spawnPerkHandler);
                        foreach (MPPerkObject selectedPerk in (IEnumerable <MPPerkObject>)peer.SelectedPerks)
                        {
                            if (selectedPerk.HasBannerBearer)
                            {
                                flag1 = true;
                                break;
                            }
                        }
                    }
                    if (num1 > 0)
                    {
                        num1 = (int)((double)num1 * (double)this.GameMode.GetTroopNumberMultiplierForMissingPlayer(peer));
                    }
                    int num2 = num1 + (flag1 ? 2 : 1);
                    IEnumerable <(EquipmentIndex, EquipmentElement)> alternativeEquipments = spawnPerkHandler?.GetAlternativeEquipments(false);
                    for (int index = 0; index < num2; ++index)
                    {
                        bool isPlayer = index == 0;
                        BasicCharacterObject basicCharacterObject = isPlayer ? heroClassForPeer.HeroCharacter : (!flag1 || index != 1 ? heroClassForPeer.TroopCharacter : heroClassForPeer.BannerBearerCharacter);
                        AgentBuildData       agentBuildData       = new AgentBuildData(basicCharacterObject);
                        if (isPlayer)
                        {
                            agentBuildData.MissionPeer(peer);
                        }
                        else
                        {
                            agentBuildData.OwningMissionPeer(peer);
                        }
                        agentBuildData.VisualsIndex(index);
                        Equipment equipment = isPlayer ? basicCharacterObject.Equipment.Clone() : Equipment.GetRandomEquipmentElements(basicCharacterObject, false, seed: MBRandom.RandomInt());
                        IEnumerable <(EquipmentIndex, EquipmentElement)> valueTuples = isPlayer ? spawnPerkHandler?.GetAlternativeEquipments(true) : alternativeEquipments;
                        if (valueTuples != null)
                        {
                            foreach ((EquipmentIndex, EquipmentElement)valueTuple in valueTuples)
                            {
                                equipment[valueTuple.Item1] = valueTuple.Item2;
                            }
                        }
                        agentBuildData.Equipment(equipment);
                        agentBuildData.Team(peer.Team);
                        agentBuildData.Formation(peer.ControlledFormation);
                        agentBuildData.IsFemale(isPlayer ? peer.Peer.IsFemale : basicCharacterObject.IsFemale);
                        agentBuildData.TroopOrigin((IAgentOriginBase) new BasicBattleAgentOrigin(basicCharacterObject));
                        BasicCultureObject basicCultureObject3 = peer.Team == this.Mission.AttackerTeam ? basicCultureObject1 : basicCultureObject2;
                        if (isPlayer)
                        {
                            agentBuildData.BodyProperties(this.GetBodyProperties(peer, peer.Team == this.Mission.AttackerTeam ? basicCultureObject1 : basicCultureObject2));
                        }
                        else
                        {
                            agentBuildData.EquipmentSeed(this.MissionLobbyComponent.GetRandomFaceSeedForCharacter(basicCharacterObject, agentBuildData.AgentVisualsIndex));
                            agentBuildData.BodyProperties(BodyProperties.GetRandomBodyProperties(agentBuildData.AgentIsFemale, basicCharacterObject.GetBodyPropertiesMin(), basicCharacterObject.GetBodyPropertiesMax(), (int)agentBuildData.AgentOverridenSpawnEquipment.HairCoverType, agentBuildData.AgentEquipmentSeed, basicCharacterObject.HairTags, basicCharacterObject.BeardTags, basicCharacterObject.TattooTags));
                        }
                        agentBuildData.ClothingColor1(peer.Team == this.Mission.AttackerTeam ? basicCultureObject3.Color : basicCultureObject3.ClothAlternativeColor);
                        agentBuildData.ClothingColor2(peer.Team == this.Mission.AttackerTeam ? basicCultureObject3.Color2 : basicCultureObject3.ClothAlternativeColor2);
                        Banner banner = new Banner(peer.Peer.BannerCode, peer.Team.Color, peer.Team.Color2);
                        agentBuildData.Banner(banner);
                        if (peer.ControlledFormation != null && peer.ControlledFormation.Banner == null)
                        {
                            peer.ControlledFormation.Banner = banner;
                        }
                        SpawnComponent   spawnComponent   = this.SpawnComponent;
                        Team             team             = peer.Team;
                        EquipmentElement equipmentElement = equipment[EquipmentIndex.ArmorItemEndSlot];
                        int         num3       = equipmentElement.Item != null ? 1 : 0;
                        int         num4       = peer.SpawnCountThisRound == 0 ? 1 : 0;
                        MatrixFrame spawnFrame = spawnComponent.GetSpawnFrame(team, num3 != 0, num4 != 0);
                        if (!spawnFrame.IsIdentity)
                        {
                            MatrixFrame matrixFrame       = spawnFrame;
                            MatrixFrame?agentInitialFrame = agentBuildData.AgentInitialFrame;
                            if ((agentInitialFrame.HasValue ? (matrixFrame != agentInitialFrame.GetValueOrDefault() ? 1 : 0) : 1) != 0)
                            {
                                agentBuildData.InitialFrame(spawnFrame);
                            }
                        }
                        if (peer.ControlledAgent != null && !isPlayer)
                        {
                            MatrixFrame frame = peer.ControlledAgent.Frame;
                            frame.rotation.OrthonormalizeAccordingToForwardAndKeepUpAsZAxis();
                            MatrixFrame matrixFrame = frame;
                            matrixFrame.origin -= matrixFrame.rotation.f.NormalizedCopy() * 3.5f;
                            Mat3 rotation = matrixFrame.rotation;
                            rotation.MakeUnit();
                            equipmentElement = basicCharacterObject.Equipment[EquipmentIndex.ArmorItemEndSlot];
                            bool flag2 = !equipmentElement.IsEmpty;
                            int  num5  = Math.Min(num2, 10);
                            List <WorldFrame> formationCreation = Formation.GetFormationFramesForBeforeFormationCreation((float)((double)num5 * (double)Formation.GetDefaultUnitDiameter(flag2) + (double)(num5 - 1) * (double)Formation.GetDefaultMinimumInterval(flag2)), num2, flag2, new WorldPosition(Mission.Current.Scene, matrixFrame.origin), rotation);
                            agentBuildData.InitialFrame(formationCreation[index - 1].ToGroundMatrixFrame());
                        }
                        Agent agent = this.Mission.SpawnAgent(agentBuildData, true);
                        agent.AddComponent((AgentComponent) new MPPerksAgentComponent(agent));
                        agent.MountAgent?.UpdateAgentProperties();
                        float num6 = spawnPerkHandler != null?spawnPerkHandler.GetHitpoints(isPlayer) : 0.0f;

                        agent.HealthLimit += num6;
                        agent.Health       = agent.HealthLimit;
                        agent.AddComponent((AgentComponent) new AgentAIStateFlagComponent(agent));
                        if (!isPlayer)
                        {
                            agent.SetWatchState(AgentAIStateFlagComponent.WatchState.Alarmed);
                        }
                        agent.WieldInitialWeapons();
                        if (isPlayer)
                        {
                            Action <MissionPeer> spawnedFromVisuals = this.OnPeerSpawnedFromVisuals;
                            if (spawnedFromVisuals != null)
                            {
                                spawnedFromVisuals(peer);
                            }
                        }
                    }
                    ++peer.SpawnCountThisRound;
                    Action <MissionPeer> spawnedFromVisuals1 = this.OnAllAgentsFromPeerSpawnedFromVisuals;
                    if (spawnedFromVisuals1 != null)
                    {
                        spawnedFromVisuals1(peer);
                    }
                    this.AgentVisualSpawnComponent.RemoveAgentVisuals(peer, true);
                    MPPerkObject.GetPerkHandler(peer)?.OnEvent(MPPerkCondition.PerkEventFlags.SpawnEnd);
                }
            }
            if (this.IsSpawningEnabled || !this.IsRoundInProgress())
            {
                return;
            }
            if ((double)this.SpawningDelayTimer >= (double)this.SpawningEndDelay && !this._hasCalledSpawningEnded)
            {
                Mission.Current.AllowAiTicking = true;
                if (this.OnSpawningEnded != null)
                {
                    this.OnSpawningEnded();
                }
                this._hasCalledSpawningEnded = true;
            }
            this.SpawningDelayTimer += dt;
        }
        protected override void SpawnAgents()
        {
            BasicCultureObject cultureLimit1 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam1.GetStrValue());
            BasicCultureObject cultureLimit2 = MBObjectManager.Instance.GetObject <BasicCultureObject>(MultiplayerOptions.OptionType.CultureTeam2.GetStrValue());

            foreach (MissionPeer peer in VirtualPlayer.Peers <MissionPeer>())
            {
                NetworkCommunicator networkPeer = peer.GetNetworkPeer();
                if (networkPeer.IsSynchronized && peer.ControlledAgent == null && (!peer.HasSpawnedAgentVisuals && peer.Team != null) && (peer.Team != this.Mission.SpectatorTeam && peer.SpawnTimer.Check(MBCommon.GetTime(MBCommon.TimeType.Mission))))
                {
                    BasicCultureObject basicCultureObject = peer.Team.Side == BattleSideEnum.Attacker ? cultureLimit1 : cultureLimit2;
                    MultiplayerClassDivisions.MPHeroClass heroClassForPeer = MultiplayerClassDivisions.GetMPHeroClassForPeer(peer);
                    if (heroClassForPeer == null || heroClassForPeer.TroopCost > this.GameMode.GetCurrentGoldForPeer(peer))
                    {
                        if (peer.SelectedTroopIndex != 0)
                        {
                            peer.SelectedTroopIndex = 0;
                            GameNetwork.BeginBroadcastModuleEvent();
                            GameNetwork.WriteMessage((GameNetworkMessage) new UpdateSelectedTroopIndex(networkPeer, 0));
                            GameNetwork.EndBroadcastModuleEvent(GameNetwork.EventBroadcastFlags.ExcludeOtherTeamPlayers, networkPeer);
                        }
                    }
                    else
                    {
                        BasicCharacterObject heroCharacter = heroClassForPeer.HeroCharacter;
                        Equipment            equipment     = heroCharacter.Equipment.Clone();
                        IEnumerable <(EquipmentIndex, EquipmentElement)> alternativeEquipments = MPPerkObject.GetOnSpawnPerkHandler(peer)?.GetAlternativeEquipments(true);
                        if (alternativeEquipments != null)
                        {
                            foreach ((EquipmentIndex, EquipmentElement)tuple in alternativeEquipments)
                            {
                                equipment[tuple.Item1] = tuple.Item2;
                            }
                        }
                        AgentBuildData agentBuildData = new AgentBuildData(heroCharacter);
                        agentBuildData.MissionPeer(peer);
                        agentBuildData.Equipment(equipment);
                        agentBuildData.Team(peer.Team);
                        agentBuildData.IsFemale(peer.Peer.IsFemale);
                        agentBuildData.BodyProperties(this.GetBodyProperties(peer, peer.Team == this.Mission.AttackerTeam ? cultureLimit1 : cultureLimit2));
                        agentBuildData.VisualsIndex(0);
                        agentBuildData.ClothingColor1(peer.Team == this.Mission.AttackerTeam ? basicCultureObject.Color : basicCultureObject.ClothAlternativeColor);
                        agentBuildData.ClothingColor2(peer.Team == this.Mission.AttackerTeam ? basicCultureObject.Color2 : basicCultureObject.ClothAlternativeColor2);
                        agentBuildData.TroopOrigin((IAgentOriginBase) new BasicBattleAgentOrigin(heroCharacter));
                        if (this.GameMode.ShouldSpawnVisualsForServer(networkPeer))
                        {
                            this.AgentVisualSpawnComponent.SpawnAgentVisualsForPeer(peer, agentBuildData, peer.SelectedTroopIndex);
                        }
                        this.GameMode.HandleAgentVisualSpawning(networkPeer, agentBuildData);
                    }
                }
            }
            if (this.Mission.AttackerTeam != null)
            {
                int num = 0;
                foreach (Agent activeAgent in this.Mission.AttackerTeam.ActiveAgents)
                {
                    if (activeAgent.Character != null && activeAgent.MissionPeer == null)
                    {
                        ++num;
                    }
                }
                if (num < MultiplayerOptions.OptionType.NumberOfBotsTeam1.GetIntValue())
                {
                    this.SpawnBot(this.Mission.AttackerTeam, cultureLimit1);
                }
            }
            if (this.Mission.DefenderTeam == null)
            {
                return;
            }
            int num1 = 0;

            foreach (Agent activeAgent in this.Mission.DefenderTeam.ActiveAgents)
            {
                if (activeAgent.Character != null && activeAgent.MissionPeer == null)
                {
                    ++num1;
                }
            }
            if (num1 >= MultiplayerOptions.OptionType.NumberOfBotsTeam2.GetIntValue())
            {
                return;
            }
            this.SpawnBot(this.Mission.DefenderTeam, cultureLimit2);
        }