BL Coding Changing Village.VillageState - Null Reference Exception

正在查看此主题的用户

mr_mouflon

Recruit
Howdy all,

I've been mucking around trying to make a mod that can change the state of a village (Normal, BeingRaided, Looted etc), but I keep running into null reference exceptions. I thought it was me being dumb and bad at coding, but then when I try the game's own command "campaign.burn_village", with no mods other than the developer console, I get the same issue - null reference exception and crash. Presumably this means there's something wonky in the vanilla code? But since the game can obviously change village states OK during normal play, I figure there must be some way to get it working.

I've tried setting the VillageState directly:
settlement.Village.VillageState = Village.VillageStates.Looted;

and also using the Action:
ChangeVillageStateAction.ApplyBySettingToLooted(settlement, MobileParty.MainParty);

But either way I get the exception. Any clues? Or, has anyone seen a mod out there that does successfully change village states, so I can sneak a peek at it and see what they did?

Here's the full script, for reference. Mostly cribbed from CampaignSystem.CampaignCheats.BurnVillage:

C#:
        [CommandLineFunctionality.CommandLineArgumentFunction("village_burn", "campaign")]
        public static string VillageBurn(List<string> strings)
        {
            if (Campaign.Current == null)
            {
                return "Campaign is null";
            }
            if (CampaignCheats.CheckParameters(strings, 0) || CampaignCheats.CheckHelp(strings))
            {
                return "Format is \"campaign.village_burn [Village Name]\"";
            }

            string villageName = string.Join(" ", strings.ToArray()).Trim(new char[]
            {
                '"'
            });

            Settlement village = Settlement.FindFirst((Settlement x) => x.Name.ToString().ToLower().Contains(villageName.ToLower()));

            if (village == null)
            {
                return "Settlement is not found";
            }
            if (!village.IsVillage)
            {
                return "Settlement is not a village.";
            }

            InformationManager.DisplayMessage(new InformationMessage($"{village.SettlementHitPoints} hp"));

            IncreaseSettlementHealthAction.Apply(village, -1);

            InformationManager.DisplayMessage(new InformationMessage($"{village.SettlementHitPoints} hp"));

            // village.Village.VillageState = Village.VillageStates.Looted;

            // ChangeVillageStateAction.ApplyBySettingToLooted(village, MobileParty.MainParty);

            village.Party.Visuals.RefreshLevelMask(village.Party);
            village.Party.Visuals.SetMapIconAsDirty();
            return "Success";
        }

If I run it as above, with the offending line(s) commented out, i can confirm it targets the correct village and applies the other changes (hp and map icon change). But the moment I try to mess with the village state, it breaks.
 
后退
顶部 底部