搜索结果: *

  1. Companions - Cannot locate (based on Encyclopedia)

    I have written about this in mod development here


    To summarise, the companions when they are created at a new campaign start are not actually activated. They are actually active with this code below when you enter a settlement for the first time. To put this on the simple term:

    If you are the main character and you enter a town and no companion has spawn there.

    -Choose a random companion ( but slightly weighted so the companion assigned settlements is a kind of match to the town you are in)
    -Activate
    -and put this town as yes a companion has spawned here.

    So what you are actually seeing is when they spawn a companion they are also given a settlement in their name. This is what the encyclopedia is reading and showing but they have not been activated.

    So to solve this simply make sure you visit the same amount of encyclopedia companions you have to the same amount of unique towns you visit. Essentially activating them all and make your encyclopedia accurate.

    The only fix I found is the one I put on the mod,
    It increases the number of companions spawned and allows a new companion to spawn every time you enter a town.
    But I am just about to release it as a standalone. and it's not compatible with 1.0.7

    Hope this helps.



    C#:
    // TaleWorlds.CampaignSystem.SandBox.CampaignBehaviors.UrbanCharactersCampaignBehavior
    // Token: 0x060025B1 RID: 9649
    public void OnSettlementEntered(MobileParty mobileParty, Settlement settlement, Hero hero)
    {
        if (mobileParty == MobileParty.MainParty && settlement.IsTown && !this._companionSettlements.ContainsKey(settlement) && this._companions.Count > 0)
        {
            int index = 0;
            MBRandom.ChooseWeighted<Hero>(this._companions, (Hero x) => (float)((x.Culture == settlement.Culture) ? 5 : 1), out index);
            Hero hero2 = this._companions[index];
            hero2.ChangeState(Hero.CharacterStates.Active);
            EnterSettlementAction.ApplyForCharacterOnly(hero2, settlement);
            this._companionSettlements.Add(settlement, CampaignTime.Now);
            this._companions.Remove(hero2);
        }
  2. Adding Companions/Wanderers - Research and Development

    Nice work,

    I am still working on trying to get this to a mod but its proofing actually a lot harder than expected.

    First things first if you want more variety of companions I simply put the is a template to the XML list and made into a mod here.

    https://www.nexusmods.com/mountandblade2bannerlord/mods/76


    the Onentersettlment method you are correct. It is a random choice but is weighted so it close to someone with a similar culture to that settlement.
    Eventually, if you want to spawn when you are on a certain settlement we can change that to say its matching then spawn them.

    The skills I am not sure about. There are not on the system and definitely tested them on the system and everything up to the scout skill are not done individually. The first 10 skills are altered by there preset skills. From 1-5.

    this.TraitKnightFightingSkills,
    this.TraitCavalryFightingSkills,
    this.TraitHorseArcherFightingSkills,
    this.TraitHuscarlFightingSkills,
    this.TraitHopliteFightingSkills,
    this.TraitArcherFIghtingSkills,
    this.TraitCrossbowmanStyle,
    this.TraitPeltastFightingSkills,


    The other skills are individual are as follows.

    this.TraitPolitician, - Charm
    this.TraitManager, - Leadership and Steward
    this.TraitSurgery, - Medicine
    this.TraitTracking, -Tracking
    this.TraitRogueSkills, - Rougery
    this.TraitEngineerSkills, - Engineer
    this.TraitDesertScoutSkills, - Scout (forest, hill and desert)


    Yeah haven't touch attributes
    The price cost yes seems like just equipment is the main cost of pricing of two equipment. The level is just * 10 so that like either 10 denar or 50 denar not much.

    The dialogue is put not via the same way as the npccharacters XML files.
    Its placed on every game load here.
    C#:
    // TaleWorlds.CampaignSystem.SandBox.SandBoxManager
    
    // Token: 0x060022F0 RID: 8944 RVA: 0x00088DB4 File Offset: 0x00086FB4
    
    private void LoadXmlFiles(CampaignGameStarter gameInitializer)
    
    {
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/minor_faction_conversations.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/world_lore_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/companion_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/wanderer_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/comment_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/comment_on_action_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/trait_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/voice_strings.xml");
    
        gameInitializer.LoadGameTexts(BasePath.Name + "Modules/SandBox/ModuleData/action_strings.xml");
    
    }
    WHich is then action on gameload and onnewgamecreated here.


    C#:
        // Token: 0x060022ED RID: 8941 RVA: 0x00088D14 File Offset: 0x00086F14
            public void OnGameLoaded(object gameInitializer)
            {
                CampaignGameStarter gameInitializer2 = (CampaignGameStarter)gameInitializer;
                this.LoadXmlFiles(gameInitializer2);
                this.AddDialogs(gameInitializer2);
            }
    
            // Token: 0x060022EE RID: 8942 RVA: 0x00088D14 File Offset: 0x00086F14
            public void OnNewGameCreated(object gameInitializer)
            {
                CampaignGameStarter gameInitializer2 = (CampaignGameStarter)gameInitializer;
                this.LoadXmlFiles(gameInitializer2);
                this.AddDialogs(gameInitializer2);
            }

    So what we would do is create your own separate action that does it in our own module and create a path to it.
    C#:
    //  protected override void OnGameStart(Game game, IGameStarter gameStarterObject)
           // {
            //    if (!(game.GameType is Campaign))
                    //return;
            //    CampaignGameStarter gameInitializer = (CampaignGameStarter)gameStarterObject;
    
             //       gameInitializer.LoadGameTexts(BasePath.Name + "Modules/Your Module's Name/ModuleData/wanderer_strings.xml");
           // }
        }
    
    }

    Hope this helps again. :smile: Great work with the research though
  3. Adding Companions/Wanderers - Research and Development

    Seems like it should be possible to add them into the pool to be generated just by changing their occupation from 'Companion' to 'Wanderer'. Although it's probably harder than that, as the templates seem to be designed differently - e.g. companions have fixed names, while wanderers just have titles. Skills are setup differently as well - companions have direct levels set, e.g. 'One-Handed=100', whereas the all the active templates use Traits, e.g. 'Fighter=1' and then there's a load of code to derive skill levels from those traits.




    Wow, that's a lot of work! It will take some time to get my head around it. I was hoping to avoid delving into c# if possible but it might be inevitable.

    As for making a standalone mod, I'd check the documentation and Glorified's video series. I really don't know much about code, but just from looking at the github, it seems to be missing a dll? And then you put the dll path into SubModule.xml. Beyond that, I have no idea, sorry!

    So my problem getting wanderers to spawn is just native behaviour, if I understand you correctly? The game can generate multiple companions linked to the same settlement, but will only spawn one at a time, minimum 6 weeks apart. You don't notice normally because you're not checking the encyclopedia for every wanderer before you enter a town, and within a few months they're all out there anyway. I'll test a bit more and see if I can confirm.

    I suppose the best answer lies somewhere in that OnSettlementEntered part, making it activate all wanderers at that location. It must be possible, since the encyclopedia knows where they are. How to do it, I'm sure I don't know.

    Also, pardon me if this is dumb, but this loop you added:

    C#:
                  int num5 = 2;
                  for (int n = 0; n < num; n++)

    Shouldn't num5 and num be the same variable? Wouldn't it be nice if the answer was that simple.



    So native behaviour, yes so normally as you normally get 25 ish companions. You enter all 25 new towns than all 25 companions will be activated and on the world map. The companion settlement they were assigned to is just overwritten and a random one is chosen as you enter the town.


    so either I figure how to activate a companion when they are created will make them show as soon as they are made. Or when you enter a settlement have it instead check which companions has that settlement too and for each spawn each character.


    And yeah the num should be num5 shah, good spot :wink:
  4. Adding Companions/Wanderers - Research and Development

    COMPANION SPAWNING EXPLANATION

    Hey so I am not a programmer or know anything C# but I have managed to crack the number limit of companions. Here is the explanation of how it works. Apologies for bad coding or explaining things wrong.



    AT THE START IT CREATES A NEW LIST
    so here, it creates companion templates list and selects all the NPC character that have is template = "true" and occupation= "wanderer"

    C#:
    // Token: 0x060025A2 RID: 9634
            public void OnNewGameCreated(CampaignGameStarter campaignGameStarter)
            {
                this._companionTemplates = new List<CharacterObject>(from x in CharacterObject.Templates
                where x.Occupation == Occupation.Wanderer
                select x);
                this._nextRandomCompanionSpawnDate = CampaignTime.WeeksFromNow(this._randomCompanionSpawnFrequencyInWeeks);
                this.SpawnUrbanCharacters();
            }


    SPAWNING YOUR COMPANIONS

    So here it spawns the companions and essentially a clamp randomiser varying to the size of your list. It essentially gives you around 25 (+/-5) companions.


    C#:
    // Token: 0x060025B2 RID: 9650
            private void SpawnUrbanCharacters()
            {
    
               int count = this._companionTemplates.Count;
                float num5 = MathF.Clamp(25f / (float)count, 0.33f, 1f);
                foreach (CharacterObject companionTemplate in this._companionTemplates)
                {
                    if (MBRandom.RandomFloat < num5)
                    {
                        this.CreateCompanion(companionTemplate);
                    }
                }
                this._companions.Shuffle<Hero>();
            }

    SETTING COMPANION LIMIT
    so I changed the code into a loop and used another method of creating a companion from the "weeklytick" So here I can have as much as I want with the exact number. AWESOME!


    C#:
    // Token: 0x060025B2 RID: 9650
            private void SpawnUrbanCharacters()
            {
    int num5 = 200;
                for (int n = 0; n < num5; n++)
                {
                    CharacterObject randomElement = (from x in this._companionTemplates
                    where !this._companions.Contains(x.HeroObject)
                    select x).GetRandomElement<CharacterObject>();
                    this.CreateCompanion(randomElement ?? this._companionTemplates.GetRandomElement<CharacterObject>());
                }
                this._companions.Shuffle<Hero>();
            }


    BUT I CAN'T FIND MY COMPANION, THEY ARE NOT THERE

    The reason why you can find your companions is they are not activated yet. They don't exist yet. What is happening is an encyclopedia bug. On the create companion method, they have a part where they randomise a settlement to each new companion created.

    After a short while of running. The encyclopedia updates show these locations which can also be castles. Just to give information out I guess.


    C#:
    // Token: 0x06003365 RID: 13157
            private void CreateCompanion(CharacterObject companionTemplate)
            {
    
    settlement3 = ((list.Any<Settlement>() ? list.GetRandomElement<Settlement>().Village.Bound : settlement3) ?? Settlement.All.GetRandomElement<Settlement>());
    
    }


    HOW THEY ARE ACTUALLY ACTIVATED

    Companions are actually activated when you enter a town and nothing else using this code. Essentially the IF is if the main party is in a town and the companionsettlement list show there are no companions here but they are companion still need to be activated, spawn a new companion from the list.

    The chose of a companion of again randomised but chosen to fit closest the settlement you in by the culture and settlement they were assigned. So unfortunately until they are actually activated you can not look in your encyclopedia at the beginning choose the one you want. Only once you have gone into a town and they are randomly chosen will you be able to get them.

    C#:
    // TaleWorlds.CampaignSystem.SandBox.CampaignBehaviors.UrbanCharactersCampaignBehavior
    // Token: 0x060025AE RID: 9646
    public void OnSettlementEntered(MobileParty mobileParty, Settlement settlement, Hero hero)
    {
        if (mobileParty == MobileParty.MainParty && settlement.IsTown && !this._companionSettlements.ContainsKey(settlement) && this._companions.Count > 0)
        {
            int index = 0;
            MBRandom.ChooseWeighted<Hero>(this._companions, (Hero x) => (float)((x.Culture == settlement.Culture) ? 5 : 1), out index);
            Hero hero2 = this._companions[index];
            hero2.ChangeState(Hero.CharacterStates.Active);
            EnterSettlementAction.ApplyForCharacterOnly(hero2, settlement);
            this._companionSettlements.Add(settlement, CampaignTime.Now);
            this._companions.Remove(hero2);
        }
    }


    THE PROBLEM
    So the problem with this code is that what is happening is after you active the COMPANION it puts in a _companionSettlements.list . assigning that town to be full. Even if you recruit that companion. So after you enter a town for the first it won't spawn another companion until the next _nextRandomCompanionSpawnDate. whish is as default 6 weeks. This is the idea to make look like the companions are moving around but in reality what the code does is. It removes the _companionSettlements.list and deactivated the companions that are in the town and start all over again. So essentially it will be like you never been in that town before.

    So essentially the only way to get all your companions is you visit the very single town once will spawn a new companion until your companion number is finished.

    THE FIX

    So simple fix for this is to simply remove this part of the code and it just stops the activation adding the settlement onto the list. The IF query still thinks it's empty and will spawn another one. So going into a town, leaving and going back in again does the trick and brings out your companions!! ( banner lord essential mod is great here as allows you to click to leave. )



    C#:
     this._companionSettlements.Add(settlement, CampaignTime.Now);

    AND THERE YOU HAVE IT!!!! 200 companions filling the towns!!

    unknown.png




    NEED YOUR HELP

    now I actually need your help. So I have altered the code and everything but no idea how to make it into a standalone mod. I managed to create a project but no idea how to override the code or why it won't reference the method that is in the same class. Ive put the project in github but trust me it probably horrible wrong. I also tried to use harmony by copying clantweaker mod but yeah its probably all wrong.


    https://github.com/haybie/CompanionHoarder

    I have also made a mod here with the campaignsystem.dll so you can all see it as well.

    https://www.nexusmods.com/mountandblade2bannerlord/mods/170

    KNOWN ISSUES

    So the only main issue I have tested is that the tavern has only 5 slots available. If you keep going in and out of the same town then they start to populate the actual main town where merchants and gang leaders are. Which again is fine but of course there are only a set amount of character paths so after a while they all do start bunching together.

    unknown.png


    Once however you get to page 10 of the characters so around 50 visits...... the GUI breaks and puts all the characters into one slot.


    unknown.png




    The real question is WHY THE HELL YOU VISITING THE SAME TOWN MORE THAN 60 times in one go.
    LAST THING
    Oh last thing I did as well. When the 6 weeks happened there also code to spawn a new companion every time so I just turned this over. But the loop you can spawn as many as you want every 6 weeks, I tried 25- 50 everytime. But you might want to set a limit.
    C#:
    if (this._nextRandomCompanionSpawnDate.IsPast)
                {
                    int num = 0;
                    for (int i = 0; i < num; i++)
                    {
                        CharacterObject randomElement = (from x in this._companionTemplates
                        where !this._companions.Contains(x.HeroObject)
                        select x).GetRandomElement<CharacterObject>();
                        this.CreateCompanion(randomElement ?? this._companionTemplates.GetRandomElement<CharacterObject>());
                        this._nextRandomCompanionSpawnDate = CampaignTime.WeeksFromNow(this._randomCompanionSpawnFrequencyInWeeks);
                    }
                }
    FURTHER TESTING NEEDED

    I haven't actually tried to hire 200 companions yet so I don't actually if this breaks the game.

    I haven't tried going into battle with 200 companions so again do not know if this will break the game.

    FIXES I HAVE TRIED


    A couple of different things I have already tried and it crashed.

    Increase the number of companions spawned in a tavern at a time
    I tried adding a simple loop around the spawning part and no matter what I do it just crashes as soon as you enter the town.
    I also tried just copying the entire block so its just repeat process but same effect.


    C#:
    // Token: 0x06003360 RID: 13152 RVA: 0x000D56C8 File Offset: 0x000D38C8
            public void OnSettlementEntered(MobileParty mobileParty, Settlement settlement, Hero hero)
            {
                if (mobileParty == MobileParty.MainParty && settlement.IsTown && !this._companionSettlements.ContainsKey(settlement) && this._companions.Count > 0)
                {
                  int num5 = 2;
                  for (int n = 0; n < num; n++)
                {
                     int index = 0;
                    MBRandom.ChooseWeighted<Hero>(this._companions, (Hero x) => (float)((x.Culture == settlement.Culture) ? 5 : 1), out index);
                    Hero hero2 = this._companions[index];
                    hero2.ChangeState(Hero.CharacterStates.Active);
                    EnterSettlementAction.ApplyForCharacterOnly(hero2, settlement);
                    this._companions.Remove(hero2);
    }
                }
            }


    ACTIVATE COMPANIONS WHEN THEY ARE CREATED
    I tried moving the activation process when the companion is created which work great and even allowed companions to spawn on the castles they were assigned and the encyclopedia was correct as soon as the game started.

    Unforntately , this only works for a maximum of 15-20 companions. Assuming the coding is too linear and a lot to process as campaign starts, It crashes when you start new games and loads very slow when you try with 10 companions but just about works.

    C#:
    // Token: 0x060025B3 RID: 9651
            private void CreateCompanion(CharacterObject companionTemplate)
    
                int index = 0;
                hero = this._companions[index];
                hero.ChangeState(Hero.CharacterStates.Active);
                EnterSettlementAction.ApplyForCharacterOnly(hero, settlement3);
                this._companionSettlements.Add(settlement3, CampaignTime.Now);
                this._companions.Remove(hero);
    
    }        {


    WELL, I HOPE THIS HELPS!!
    I don't mind people making their own limit, I just ask to be credited for this haha. Glad to help people understand this part more.
  5. Garrison disappeared

    Just looked up other posts. I just lost like 200 legionnaires and palatine archers...... turns out if there is not enough food in the city the garrison just leave. So have to wait before you dropping your garrison. What a waste of troops....
  6. Game crashes every time I try to close my inventory

    Yeah just adding on here for other people. Having the same problem with inventory, just got the acquire 7 weapons quest. Can confirm waiting it out until the end of quests. Resolved this.
后退
顶部 底部