Crash at startup using my mod

Users who are viewing this thread

LawH

Recruit
I am trying to edit the practice arena a bit to see what can be done with it. The code that I have crashes the game at startup. It includes everything from the ArenaPracticeFightMissionController, as it has some values that I thought about starting with. Here is the code:

Code:
using SandBox;
using SandBox.Conversation.MissionLogics;
using SandBox.Missions.MissionLogics;
using SandBox.Missions.MissionLogics.Arena;
using System.Reflection;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.AgentOrigins;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.ComponentInterfaces;
using TaleWorlds.CampaignSystem.Encounters;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Engine;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.MountAndBlade;
namespace BannerlordRentTheArena
{
    public class SubModule : MBSubModuleBase
    {
        public override void OnMissionBehaviorInitialize(Mission mission)
        {
            base.OnMissionBehaviorInitialize(mission);
            string missionType = mission.GetType().ToString();
            //Needs a check if we are in an arena?
            //mission.AddMissionBehavior(new LessFightersInPracticeFight());
        }
    }

    internal class LessFightersInPracticeFight : ArenaPracticeFightMissionController
    {
        private int AISpawnIndex
        {
            get
            {
                return _spawnedOpponentAgentCount;
            }
        }
        public new int RemainingOpponentCountFromLastPractice { get; private set; }
        public new bool IsPlayerPracticing { get; private set; }
        public new int OpponentCountBeatenByPlayer { get; private set; }
        public new int RemainingOpponentCount
        {
            get
            {
                return 30 - _spawnedOpponentAgentCount + _aliveOpponentCount;
            }
        }
        public new bool IsPlayerSurvived { get; private set; }
        public new bool AfterPractice { get; set; }
        public override void AfterStart()
        {
            _settlement = PlayerEncounter.LocationEncounter.Settlement;
            InitializeTeams();
            GameEntity item = base.Mission.Scene.FindEntityWithTag("tournament_practice") ?? base.Mission.Scene.FindEntityWithTag("tournament_fight");
            List<GameEntity> list = Mission.Current.Scene.FindEntitiesWithTag("arena_set").ToList<GameEntity>();
            list.Remove(item);
            foreach (GameEntity gameEntity in list)
            {
                gameEntity.Remove(88);
            }
            _initialSpawnFrames = (from e in base.Mission.Scene.FindEntitiesWithTag("sp_arena")
                                        select e.GetGlobalFrame()).ToList<MatrixFrame>();
            _spawnFrames = (from e in base.Mission.Scene.FindEntitiesWithTag("sp_arena_respawn")
                                 select e.GetGlobalFrame()).ToList<MatrixFrame>();
            for (int i = 0; i < _initialSpawnFrames.Count; i++)
            {
                MatrixFrame value = _initialSpawnFrames[i];
                value.rotation.OrthonormalizeAccordingToForwardAndKeepUpAsZAxis();
                _initialSpawnFrames[i] = value;
            }
            for (int j = 0; j < _spawnFrames.Count; j++)
            {
                MatrixFrame value2 = _spawnFrames[j];
                value2.rotation.OrthonormalizeAccordingToForwardAndKeepUpAsZAxis();
                _spawnFrames[j] = value2;
            }
            IsPlayerPracticing = false;
            _participantAgents = new List<Agent>();
            StartPractice();
            MissionAgentHandler missionBehavior = base.Mission.GetMissionBehavior<MissionAgentHandler>();
            missionBehavior.SpawnPlayer(true, true, false, false, false, "");
            missionBehavior.SpawnLocationCharacters(null);
        }
        private void SpawnPlayerNearTournamentMaster()
        {
            GameEntity entity = base.Mission.Scene.FindEntityWithTag("sp_player_near_arena_master");
            base.Mission.SpawnAgent(new AgentBuildData(CharacterObject.PlayerCharacter).Team(base.Mission.PlayerTeam).InitialFrameFromSpawnPointEntity(entity).NoHorses(true).CivilianEquipment(true).TroopOrigin(new SimpleAgentOrigin(CharacterObject.PlayerCharacter, -1, null, default(UniqueTroopDescriptor))).Controller(Agent.ControllerType.Player), false);
            Mission.Current.SetMissionMode(MissionMode.StartUp, false);
        }
        private Agent SpawnArenaAgent(Team team, MatrixFrame frame)
        {
            CharacterObject characterObject;
            int spawnIndex;
            if (team == base.Mission.PlayerTeam)
            {
                characterObject = CharacterObject.PlayerCharacter;
                spawnIndex = 0;
            }
            else
            {
                characterObject = _participantCharacters[AISpawnIndex];
                spawnIndex = AISpawnIndex;
            }
            Equipment equipment = new Equipment();
            AddRandomWeapons(equipment, spawnIndex);
            AddRandomClothes(characterObject, equipment);
            Mission mission = base.Mission;
            AgentBuildData agentBuildData = new AgentBuildData(characterObject).Team(team).InitialPosition(frame.origin);
            Vec2 vec = frame.rotation.f.AsVec2;
            vec = vec.Normalized();
            Agent agent = mission.SpawnAgent(agentBuildData.InitialDirection(vec).NoHorses(true).Equipment(equipment).TroopOrigin(new SimpleAgentOrigin(characterObject, -1, null, default(UniqueTroopDescriptor))).Controller((characterObject == CharacterObject.PlayerCharacter) ? Agent.ControllerType.Player : Agent.ControllerType.AI), false);
            agent.FadeIn();
            if (characterObject != CharacterObject.PlayerCharacter)
            {
                _aliveOpponentCount++;
                _spawnedOpponentAgentCount++;
            }
            if (agent.IsAIControlled)
            {
                agent.SetWatchState(Agent.WatchState.Alarmed);
            }
            return agent;
        }
        public override void OnScoreHit(Agent affectedAgent, Agent affectorAgent, WeaponComponentData attackerWeapon, bool isBlocked, bool isSiegeEngineHit, in Blow blow, in AttackCollisionData collisionData, float damagedHp, float hitDistance, float shotDifficulty)
        {
            if (affectorAgent == null)
            {
                return;
            }
            if (affectorAgent.IsMount && affectorAgent.RiderAgent != null)
            {
                affectorAgent = affectorAgent.RiderAgent;
            }
            if (affectorAgent.Character == null || affectedAgent.Character == null)
            {
                return;
            }
            float num = (float)blow.InflictedDamage;
            if (num > affectedAgent.HealthLimit)
            {
                num = affectedAgent.HealthLimit;
            }
            float num2 = num / affectedAgent.HealthLimit;
            EnemyHitReward(affectedAgent, affectorAgent, blow.MovementSpeedDamageModifier, shotDifficulty, attackerWeapon, blow.AttackType, 0.5f * num2, num);
        }
        private void EnemyHitReward(Agent affectedAgent, Agent affectorAgent, float lastSpeedBonus, float lastShotDifficulty, WeaponComponentData attackerWeapon, AgentAttackType attackType, float hitpointRatio, float damageAmount)
        {
            CharacterObject affectedCharacter = (CharacterObject)affectedAgent.Character;
            CharacterObject affectorCharacter = (CharacterObject)affectorAgent.Character;
            if (affectedAgent.Origin != null && affectorAgent != null && affectorAgent.Origin != null)
            {
                bool flag = affectorAgent.MountAgent != null;
                bool isHorseCharge = flag && attackType == AgentAttackType.Collision;
                SkillLevelingManager.OnCombatHit(affectorCharacter, affectedCharacter, null, null, lastSpeedBonus, lastShotDifficulty, attackerWeapon, hitpointRatio, CombatXpModel.MissionTypeEnum.PracticeFight, flag, affectorAgent.Team == affectedAgent.Team, false, damageAmount, affectedAgent.Health < 1f, false, isHorseCharge);
            }
        }
        public override void OnMissionTick(float dt)
        {
            base.OnMissionTick(dt);
            if (_aliveOpponentCount < 2 && _spawnedOpponentAgentCount < 15 && (_aliveOpponentCount == 1 || _nextSpawnTime < base.Mission.CurrentTime))
            {
                Team team = SelectRandomAiTeam();
                Agent item = SpawnArenaAgent(team, GetSpawnFrame(true, false));
                _participantAgents.Add(item);
                _nextSpawnTime = base.Mission.CurrentTime + 14f - (float)_spawnedOpponentAgentCount / 3f;
                if (_spawnedOpponentAgentCount == 30 && !IsPlayerPracticing)
                {
                    _spawnedOpponentAgentCount = 0;
                }
            }
            if (_teleportTimer == null && IsPlayerPracticing && CheckPracticeEndedForPlayer())
            {
                _teleportTimer = new BasicMissionTimer();
                IsPlayerSurvived = (base.Mission.MainAgent != null && base.Mission.MainAgent.IsActive());
                if (IsPlayerSurvived)
                {
                    MBInformationManager.AddQuickInformation(new TextObject("{=seyti8xR}Victory!", null), 0, null, "event:/ui/mission/arena_victory");
                }
                AfterPractice = true;
            }
            if (_teleportTimer != null && _teleportTimer.ElapsedTime > (float)TeleportTime)
            {
                _teleportTimer = null;
                RemainingOpponentCountFromLastPractice = RemainingOpponentCount;
                IsPlayerPracticing = false;
                StartPractice();
                SpawnPlayerNearTournamentMaster();
                Agent? agent = base.Mission.Agents.FirstOrDefault((Agent x) => x.Character != null && ((CharacterObject)x.Character).Occupation == Occupation.ArenaMaster);
                MissionConversationLogic.Current.StartConversation(agent, true, false);
            }
        }
        private Team SelectRandomAiTeam()
        {
            Team? team = null;
            foreach (Team team2 in _AIParticipantTeams)
            {
                if (!team2.HasBots)
                {
                    team = team2;
                    break;
                }
            }
            if (team == null)
            {
                team = _AIParticipantTeams[MBRandom.RandomInt(_AIParticipantTeams.Count - 1) + 1];
            }
            return team;
        }
        public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState, KillingBlow killingBlow)
        {
            if (affectedAgent != null && affectedAgent.IsHuman)
            {
                if (affectedAgent != Agent.Main)
                {
                    _aliveOpponentCount--;
                }
                if (affectorAgent != null && affectorAgent.IsHuman && affectorAgent == Agent.Main && affectedAgent != Agent.Main)
                {
                    int opponentCountBeatenByPlayer = OpponentCountBeatenByPlayer;
                    OpponentCountBeatenByPlayer = opponentCountBeatenByPlayer + 1;
                }
            }
            if (_participantAgents.Contains(affectedAgent))
            {
                _participantAgents.Remove(affectedAgent);
            }
        }
        public override bool MissionEnded(ref MissionResult missionResult)
        {
            return false;
        }
        public override InquiryData OnEndMissionRequest(out bool canPlayerLeave)
        {
            canPlayerLeave = true;
            if (!IsPlayerPracticing)
            {
                return null;
            }
            return new InquiryData(new TextObject("{=zv49qE35}Practice Fight", null).ToString(), GameTexts.FindText("str_give_up_fight", null).ToString(), true, true, GameTexts.FindText("str_ok", null).ToString(), GameTexts.FindText("str_cancel", null).ToString(), new Action(base.Mission.OnEndMissionResult), null, "", 0f, null, null, null);
        }
        public new void StartPlayerPractice()
        {
            IsPlayerPracticing = true;
            AfterPractice = false;
            StartPractice();
        }
        private void StartPractice()
        {
            InitializeParticipantCharacters();
            SandBoxHelpers.MissionHelper.FadeOutAgents(from agent in base.Mission.Agents
                                                       where _participantAgents.Contains(agent) || agent.IsMount || agent.IsPlayerControlled
                                                       select agent, true, false);
            _spawnedOpponentAgentCount = 0;
            _aliveOpponentCount = 0;
            _participantAgents.Clear();
            Mission.Current.ClearCorpses(false);
            base.Mission.RemoveSpawnedItemsAndMissiles();
            ArrangePlayerTeamEnmity();
            if (IsPlayerPracticing)
            {
                Agent agent2 = SpawnArenaAgent(base.Mission.PlayerTeam, GetSpawnFrame(false, true));
                agent2.WieldInitialWeapons(Agent.WeaponWieldActionType.InstantAfterPickUp, Equipment.InitialWeaponEquipPreference.Any);
                OpponentCountBeatenByPlayer = 0;
                _participantAgents.Add(agent2);
            }
            int count = _AIParticipantTeams.Count;
            int num = 0;
            while (_spawnedOpponentAgentCount < 6)
            {
                _participantAgents.Add(SpawnArenaAgent(_AIParticipantTeams[num % count], GetSpawnFrame(false, true)));
                num++;
            }
            _nextSpawnTime = base.Mission.CurrentTime + 14f;
        }
        private bool CheckPracticeEndedForPlayer()
        {
            return base.Mission.MainAgent == null || !base.Mission.MainAgent.IsActive() || RemainingOpponentCount == 0;
        }
        private void AddRandomWeapons(Equipment equipment, int spawnIndex)
        {
            int num = 1 + spawnIndex * 3 / 30;
            List<Equipment> list = (Game.Current.ObjectManager.GetObject<CharacterObject>(string.Concat(new object[]
            {
        "weapon_practice_stage_",
        num,
        "_",
        _settlement.MapFaction.Culture.StringId
            })) ?? Game.Current.ObjectManager.GetObject<CharacterObject>("weapon_practice_stage_" + num + "_empire")).BattleEquipments.ToList<Equipment>();
            int index = MBRandom.RandomInt(list.Count);
            for (int i = 0; i <= 3; i++)
            {
                EquipmentElement equipmentFromSlot = list[index].GetEquipmentFromSlot((EquipmentIndex)i);
                if (equipmentFromSlot.Item != null)
                {
                    equipment.AddEquipmentToSlotWithoutAgent((EquipmentIndex)i, equipmentFromSlot);
                }
            }
        }
        private void AddRandomClothes(CharacterObject troop, Equipment equipment)
        {
            Equipment participantArmor = Campaign.Current.Models.TournamentModel.GetParticipantArmor(troop);
            for (int i = 0; i < 12; i++)
            {
                if (i > 4 && i != 10 && i != 11)
                {
                    EquipmentElement equipmentFromSlot = participantArmor.GetEquipmentFromSlot((EquipmentIndex)i);
                    if (equipmentFromSlot.Item != null)
                    {
                        equipment.AddEquipmentToSlotWithoutAgent((EquipmentIndex)i, equipmentFromSlot);
                    }
                }
            }
        }
        private void InitializeTeams()
        {
            _AIParticipantTeams = new List<Team>();
            base.Mission.Teams.Add(BattleSideEnum.Defender, Hero.MainHero.MapFaction.Color, Hero.MainHero.MapFaction.Color2, null, true, false, true);
            base.Mission.PlayerTeam = base.Mission.DefenderTeam;
            _tournamentMasterTeam = base.Mission.Teams.Add(BattleSideEnum.None, _settlement.MapFaction.Color, _settlement.MapFaction.Color2, null, true, false, true);
            while (_AIParticipantTeams.Count < 6)
            {
                _AIParticipantTeams.Add(base.Mission.Teams.Add(BattleSideEnum.Attacker, uint.MaxValue, uint.MaxValue, null, true, false, true));
            }
            for (int i = 0; i < _AIParticipantTeams.Count; i++)
            {
                _AIParticipantTeams[i].SetIsEnemyOf(_tournamentMasterTeam, false);
                for (int j = i + 1; j < _AIParticipantTeams.Count; j++)
                {
                    _AIParticipantTeams[i].SetIsEnemyOf(_AIParticipantTeams[j], true);
                }
            }
        }
        private void InitializeParticipantCharacters()
        {
            List<CharacterObject> participantCharacters = GetParticipantCharacters(_settlement);
            _participantCharacters = (from x in participantCharacters
                                           orderby x.Level
                                           select x).ToList<CharacterObject>();
        }
        public new static List<CharacterObject> GetParticipantCharacters(Settlement settlement)
        {
            int num = 30;
            List<CharacterObject> list = new List<CharacterObject>();
            int num2 = 0;
            int num3 = 0;
            int num4 = 0;
            if (list.Count < num && settlement.Town.GarrisonParty != null)
            {
                foreach (TroopRosterElement troopRosterElement in settlement.Town.GarrisonParty.MemberRoster.GetTroopRoster())
                {
                    int num5 = num - list.Count;
                    if (!list.Contains(troopRosterElement.Character) && troopRosterElement.Character.Tier == 3 && (float)num5 * 0.4f > (float)num2)
                    {
                        list.Add(troopRosterElement.Character);
                        num2++;
                    }
                    else if (!list.Contains(troopRosterElement.Character) && troopRosterElement.Character.Tier == 4 && (float)num5 * 0.4f > (float)num3)
                    {
                        list.Add(troopRosterElement.Character);
                        num3++;
                    }
                    else if (!list.Contains(troopRosterElement.Character) && troopRosterElement.Character.Tier == 5 && (float)num5 * 0.2f > (float)num4)
                    {
                        list.Add(troopRosterElement.Character);
                        num4++;
                    }
                    if (list.Count >= num)
                    {
                        break;
                    }
                }
            }
            if (list.Count < num)
            {
                List<CharacterObject> list2 = new List<CharacterObject>();
                GetUpgradeTargets(((settlement != null) ? settlement.Culture : Game.Current.ObjectManager.GetObject<CultureObject>("empire")).BasicTroop, ref list2);
                int num6 = num - list.Count;
                using (List<CharacterObject>.Enumerator enumerator2 = list2.GetEnumerator())
                {
                    while (enumerator2.MoveNext())
                    {
                        CharacterObject characterObject = enumerator2.Current;
                        if (!list.Contains(characterObject) && characterObject.Tier == 3 && (float)num6 * 0.4f > (float)num2)
                        {
                            list.Add(characterObject);
                            num2++;
                        }
                        else if (!list.Contains(characterObject) && characterObject.Tier == 4 && (float)num6 * 0.4f > (float)num3)
                        {
                            list.Add(characterObject);
                            num3++;
                        }
                        else if (!list.Contains(characterObject) && characterObject.Tier == 5 && (float)num6 * 0.2f > (float)num4)
                        {
                            list.Add(characterObject);
                            num4++;
                        }
                        if (list.Count >= num)
                        {
                            break;
                        }
                    }
                    goto IL_284;
                }
            IL_256:
                int num7 = 0;
                while (num7 < list2.Count && list.Count < num)
                {
                    list.Add(list2[num7]);
                    num7++;
                }
            IL_284:
                if (list.Count < num)
                {
                    goto IL_256;
                }
            }
            return list;
        }
        private static void GetUpgradeTargets(CharacterObject troop, ref List<CharacterObject> list)
        {
            if (!list.Contains(troop) && troop.Tier >= 3)
            {
                list.Add(troop);
            }
            CharacterObject[] upgradeTargets = troop.UpgradeTargets;
            for (int i = 0; i < upgradeTargets.Length; i++)
            {
                GetUpgradeTargets(upgradeTargets[i], ref list);
            }
        }
        private void ArrangePlayerTeamEnmity()
        {
            foreach (Team team in _AIParticipantTeams)
            {
                team.SetIsEnemyOf(base.Mission.PlayerTeam, IsPlayerPracticing);
            }
        }
        private Team GetStrongestTeamExceptPlayerTeam()
        {
            Team? result = null;
            int num = -1;
            foreach (Team team in _AIParticipantTeams)
            {
                int num2 = CalculateTeamPower(team);
                if (num2 > num)
                {
                    result = team;
                    num = num2;
                }
            }
            return result;
        }
        private int CalculateTeamPower(Team team)
        {
            int num = 0;
            foreach (Agent agent in team.ActiveAgents)
            {
                num += agent.Character.Level * agent.KillCount + (int)TaleWorlds.Library.MathF.Sqrt(agent.Health);
            }
            return num;
        }
        private MatrixFrame GetSpawnFrame(bool considerPlayerDistance, bool isInitialSpawn)
        {
            List<MatrixFrame> list = (isInitialSpawn || _spawnFrames.IsEmpty<MatrixFrame>()) ? _initialSpawnFrames : _spawnFrames;
            if (list.Count == 1)
            {
                Debug.FailedAssert("Spawn point count is wrong! Arena practice spawn point set should be used in arena scenes.", "C:\\Develop\\MB3\\Source\\Bannerlord\\SandBox\\Missions\\MissionLogics\\Arena\\cs", "GetSpawnFrame", 615);
                return list[0];
            }
            MatrixFrame result;
            if (considerPlayerDistance && Agent.Main != null && Agent.Main.IsActive())
            {
                int num = MBRandom.RandomInt(list.Count);
                result = list[num];
                float num2 = float.MinValue;
                for (int i = num + 1; i < num + list.Count; i++)
                {
                    MatrixFrame matrixFrame = list[i % list.Count];
                    float num3 = CalculateLocationScore(matrixFrame);
                    if (num3 >= 100f)
                    {
                        result = matrixFrame;
                        break;
                    }
                    if (num3 > num2)
                    {
                        result = matrixFrame;
                        num2 = num3;
                    }
                }
            }
            else
            {
                int num4 = _spawnedOpponentAgentCount;
                if (IsPlayerPracticing && Agent.Main != null)
                {
                    num4++;
                }
                result = list[num4 % list.Count];
            }
            return result;
        }
        private float CalculateLocationScore(MatrixFrame matrixFrame)
        {
            float num = 100f;
            float num2 = 0.25f;
            float num3 = 0.75f;
            if (matrixFrame.origin.DistanceSquared(Agent.Main.Position) < 144f)
            {
                num *= num2;
            }
            for (int i = 0; i < _participantAgents.Count; i++)
            {
                if (_participantAgents[i].Position.DistanceSquared(matrixFrame.origin) < 144f)
                {
                    num *= num3;
                }
            }
            return num;
        }
        private const int AIParticipantCount = 30;
        private const int MaxAliveAgentCount = 6;
        private const int MaxSpawnInterval = 14;
        private const int MinSpawnDistanceSquared = 144;
        private const int TotalStageCount = 3;
        private const int PracticeFightTroopTierLimit = 3;
        public new int TeleportTime = 5;
        private Settlement? _settlement;
        private int _spawnedOpponentAgentCount;
        private int _aliveOpponentCount;
        private float _nextSpawnTime;
        private List<MatrixFrame>? _initialSpawnFrames;
        private List<MatrixFrame>? _spawnFrames;
        private List<Team>? _AIParticipantTeams;
        private List<Agent>? _participantAgents;
        private Team? _tournamentMasterTeam;
        private BasicMissionTimer? _teleportTimer;
        private List<CharacterObject>? _participantCharacters;
        private const float XpShareForKill = 0.5f;
        private const float XpShareForDamage = 0.5f;
        //*/
    }
}
With my little understanding, I can't see the issue. Any help is appreciated. Thanks!
 
Back
Top Bottom