Any way to force spawn NPCs? (Vassals)

Users who are viewing this thread

First of all I'm playing on Floris Expanded 2.54, but I'm posting here because the Floris and Diplomacy subforums are completely deserted. There's no activity there, I've posted threads asking questions there and they've all received a grand total of zero replies... Also, hours of Googling have returned dozens of returns on steamcommunity and this forum, where no solution has ever been found.

The problem is with a Diplomacy feature (included in Floris) with vassals returning from exile. A message will say they've returned. They appear on the Notes --> Characters list. But they're not spawned. Their wives/daughters/sisters spawn. When you ask a vassal "I want to know the location of someone", they're not even on the list. On the Notes --> Factions --> (Faction of vassal) page, their names aren't on the list of vassals.

Here's another person who faced this exact problem 5 years ago. The modder's solution was to ask for his savegame and he modified it directly. Something about "He had slot_troop_occupation set to slto_inactive instead of slto_kingdom_hero".

I've also tried changing the the returning from exile option from Enabled, to Disabled, to Frequent. That didn't make a difference.

The game started with ~130 lords. Now there are ~75.

I need a way to force them to spawn and be active. Something about what the modder said about "slot_troop_occupation set to slto_inactive instead of slto_kingdom_hero". I don't know how to modify savegames. I've tried MnBSaveGameEditor but I don't find any slot_troop_occupation variable...
 
I'm afraid you'll probably just have to get used to the lords not coming back then. There's a chance that a trigger or something will fire later on and everything will be ok, but this seems to be caused by problems from the code itself forgetting to change the slto_ value. Floris is open-source, so you would be able to change the code yourself and it should even be savegame compatible (just making a new simple trigger, which iirc works with saves) but you'd have to learn enough modding skills to make it which is probably not worth the effort. As a last-ditch attempt you could try PMing one of the Floris modmakers directly, but no doubt they get floods of PMs from people all the time so even if they receive it they might not answer.
 
Ruthven said:
I'm afraid you'll probably just have to get used to the lords not coming back then. There's a chance that a trigger or something will fire later on and everything will be ok, but this seems to be caused by problems from the code itself forgetting to change the slto_ value. Floris is open-source, so you would be able to change the code yourself and it should even be savegame compatible (just making a new simple trigger, which iirc works with saves) but you'd have to learn enough modding skills to make it which is probably not worth the effort. As a last-ditch attempt you could try PMing one of the Floris modmakers directly, but no doubt they get floods of PMs from people all the time so even if they receive it they might not answer.
I've put many hours into my save so I think I could try modding itself. Hopefully it's as simple a solution as implementing a new, simple trigger.

Any chance you can give me a head start or a heads up on some good resources on where to start off modding, especially if I'm going to dig into Floris' source?
 
This thread is a good start: https://forums.taleworlds.com/index.php/topic,240255.0.html

It might be good to familiarize yourself with how the module system works in warband. Make a backup of your mod and savegame before trying to mod it, and note that it will overwrite any edits made with morgh's editor and other text-editor tools.

But lucky for you this shouldn't be too difficult. Download the floris source (I think included in the "dev suite" version of floris?) and open module_scripts, and search for "dplmc_lord_return_from_exile". This is the script you'll need to fix to get the lords working again. I don't have the floris source myself so I don't know the exact way it's coded but you should only need to add one or two lines.
 
Ruthven said:
This thread is a good start: https://forums.taleworlds.com/index.php/topic,240255.0.html

It might be good to familiarize yourself with how the module system works in warband. Make a backup of your mod and savegame before trying to mod it, and note that it will overwrite any edits made with morgh's editor and other text-editor tools.

But lucky for you this shouldn't be too difficult. Download the floris source (I think included in the "dev suite" version of floris?) and open module_scripts, and search for "dplmc_lord_return_from_exile". This is the script you'll need to fix to get the lords working again. I don't have the floris source myself so I don't know the exact way it's coded but you should only need to add one or two lines.
I really appreciate you helping me out here.

What I've found so far are about 100 lines for this section: http://i.imgur.com/fOfx5CW.png

This is the whole section:
Code:
							  #script_dplmc_lord_return_from_exile
						  # INPUT: arg1 = troop_id, arg2 = new faction_no
						  # OUTPUT: none
						  ("dplmc_lord_return_from_exile",
							[
							  (store_script_param_1, ":troop_no"),
							  (store_script_param_2, ":faction_no"),
							  #Check validity
							  (try_begin),
								  (is_between, ":troop_no", heroes_begin, heroes_end),
								  (is_between, ":faction_no", kingdoms_begin, kingdoms_end),
								  (neq, ":troop_no", "trp_player"),
								  (faction_get_slot, ":faction_liege", ":faction_no", slot_faction_leader),
								  #The lord definitely should not already belong to a kingdom
								  (store_troop_faction, ":old_faction", ":troop_no"),
								  (neg|is_between, ":old_faction", kingdoms_begin, kingdoms_end),
								  (try_begin),
									#Handle separately for adding to the player's faction
									#The player may decide to accept or reject the return
									(this_or_next|eq, ":faction_liege", "trp_player"),
									(eq, ":faction_no", "fac_player_supporters_faction"),
									#(eq, 1, 0),#<-- temporarily disable
									#Lord comes to petition the player instead of automatically returning
									(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
									(troop_set_slot, ":troop_no", slot_troop_occupation, slto_inactive),
									#Show event (no log without actual faction change)
									(str_store_troop_name, s4, ":troop_no"),
									(str_store_faction_name, s5, ":faction_no"),
									(str_store_troop_name, s6, ":faction_liege"),
									(display_message, "@{s4} has returned from exile, seeking refuge with {s6} of {s5}."),
									#Remove party
									(troop_get_slot, ":led_party", ":troop_no", slot_troop_leaded_party),
									(try_begin),
										(party_is_active, ":led_party"),
										(neq, ":led_party", "p_main_party"),
										(remove_party, ":led_party"),
										(troop_set_slot, ":troop_no", slot_troop_leaded_party, -1),
									(try_end),
									#
								  (else_try),
									 #NPC king auto-accepts
									 #Normalize relation between NPC and king
									 (call_script, "script_troop_get_relation_with_troop", ":troop_no", ":faction_liege"),
									 (store_sub, ":relation_change", 0, reg0),#enough to increase to 0 if negative
									 (val_max, ":relation_change", 5),
									 (call_script, "script_troop_change_relation_with_troop", ":troop_no", ":faction_liege", ":relation_change"),
									 #Perform reverse of relation change for exile
									 (try_for_range, ":active_npc", active_npcs_begin, active_npcs_end), #all lords in own faction, and relatives regardless of faction
										(assign, ":relation_change", 0),#no change for non-relatives in other factions
										(try_begin),
											(store_faction_of_troop, ":active_npc_faction", ":active_npc"),
											(eq, ":faction_no", ":active_npc_faction"),
											#Auto-exiling someone at -75 relation to his liege gives a -1 base
											#relation penalty from other lords, so the gain is 1 by default.
											(assign, ":relation_change", 1),
										(try_end),
										##(call_script, "script_troop_get_family_relation_to_troop", ":troop_no", ":active_npc"),
										(call_script, "script_dplmc_troop_get_family_relation_to_troop", ":troop_no", ":active_npc"),
										(assign, ":family_relation", reg0),
										(try_begin),
											(gt, ":family_relation", 1),
											(store_div, ":family_modifier", reg0, 3),
											(val_add, ":relation_change", ":family_modifier"),
										(try_end),
										
										(neq, ":relation_change", 0),
										
										(call_script, "script_troop_change_relation_with_troop", ":faction_liege", ":active_npc", ":relation_change"),
										(try_begin),
											(eq, "$cheat_mode", 1),
											(str_store_troop_name, s17, ":active_npc"),
											(str_store_troop_name, s18, ":faction_liege"),
											(assign, reg3, ":relation_change"),
											(display_message, "str_trial_influences_s17s_relation_with_s18_by_reg3"),
										(try_end),
									 (try_end),#end try for range :active_npc
									 
									#Now actually change the faction
									(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
									(try_begin), #new-begin
										(neq, ":faction_no", "fac_player_supporters_faction"),
										(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive),
											(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement),
										(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero),
									(try_end), #new-end
									
									#Log event
									(str_store_troop_name, s4, ":troop_no"),
									(str_store_faction_name, s5, ":faction_no"),
									(str_store_troop_name, s6, ":faction_liege"),
									(display_log_message, "@{s4} has been granted a pardon by {s6} of {s5} and has returned from exile."),

									(troop_get_slot, ":led_party", ":troop_no", slot_troop_leaded_party),
									(try_begin),
										(party_is_active, ":led_party"),
										(neq, ":led_party", "p_main_party"),
										(remove_party, ":led_party"),
										(troop_set_slot, ":troop_no", slot_troop_leaded_party, -1),
									(try_end),
								  (try_end),#end NPC king auto-accepts
							  (else_try),
								#Failure.  Perform string register assignment first to avoid differences
								#between debug and non-debug behavior.
								(str_store_troop_name, s5, ":troop_no"),
								(str_store_faction_name, s7, ":faction_no"),
								#(ge, "$cheat_mode", 1),#<-- always show this
								(display_message, "@{!}DEBUG : failure in dplmc_lord_return_from_exile((s5}, {s7})"),
							  (try_end),
							]),

There are 2 lines that have slto_inactive, and one line with slto_kingdom_hero:
(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero),

As far as I know, from this thread: http://forums.taleworlds.com/index.php?topic=181224.0 the problem is that the Lord needs to have his slto_inactive set to slto_kingdom_hero. Something is wrong with the code that it's not being set to slto_kingdom_hero. I've just been looking through for about 10 minutes and I don't see what the problem is yet, but maybe you could spot it way faster and quicker than I can.

Here's the full module_scripts.py file, anyway, if you'd like to take a look yourself: http://www.megafileupload.com/ohxV/module_scripts.py
 
chuhrros said:
  #script_dplmc_lord_return_from_exile
  # INPUT: arg1 = troop_id, arg2 = new faction_no
  # OUTPUT: none
  ("dplmc_lord_return_from_exile",
[
  (store_script_param_1, ":troop_no"),
  (store_script_param_2, ":faction_no"),
  #Check validity
  (try_begin),
  (is_between, ":troop_no", heroes_begin, heroes_end),
  (is_between, ":faction_no", kingdoms_begin, kingdoms_end),
  (neq, ":troop_no", "trp_player"),
  (faction_get_slot, ":faction_liege", ":faction_no", slot_faction_leader),
  #The lord definitely should not already belong to a kingdom
  (store_troop_faction, ":eek:ld_faction", ":troop_no"),
  (neg|is_between, ":eek:ld_faction", kingdoms_begin, kingdoms_end),
  (try_begin),
#Handle separately for adding to the player's faction
#The player may decide to accept or reject the return
(this_or_next|eq, ":faction_liege", "trp_player"),
(eq, ":faction_no", "fac_player_supporters_faction"),
#(eq, 1, 0),#<-- temporarily disable
#Lord comes to petition the player instead of automatically returning
(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
(troop_set_slot, ":troop_no", slot_troop_occupation, slto_inactive),
#Show event (no log without actual faction change)
(str_store_troop_name, s4, ":troop_no"),
(str_store_faction_name, s5, ":faction_no"),
(str_store_troop_name, s6, ":faction_liege"),
(display_message, "@{s4} has returned from exile, seeking refuge with {s6} of {s5}."),
#Remove party
etc
]),
Quick question, but did the vassal returning from exile join your faction or an NPC? It looks like this might be a pretty simple fix, I am pretty sure all you need to do is change the blue slto_inactive to slto_kingdom_hero. However it looks like lords which are members of a faction will be ignored by this code, so though it might start working from this point on it may not fix any of the lords who have already tried to re-spawn. But probably we can make a trigger that will force them back. For now try testing with this small change and see what happens. Remember again to back everything up in case something goes wrong.
 
Ruthven said:
chuhrros said:
  #script_dplmc_lord_return_from_exile
  # INPUT: arg1 = troop_id, arg2 = new faction_no
  # OUTPUT: none
  ("dplmc_lord_return_from_exile",
[
  (store_script_param_1, ":troop_no"),
  (store_script_param_2, ":faction_no"),
  #Check validity
  (try_begin),
  (is_between, ":troop_no", heroes_begin, heroes_end),
  (is_between, ":faction_no", kingdoms_begin, kingdoms_end),
  (neq, ":troop_no", "trp_player"),
  (faction_get_slot, ":faction_liege", ":faction_no", slot_faction_leader),
  #The lord definitely should not already belong to a kingdom
  (store_troop_faction, ":eek:ld_faction", ":troop_no"),
  (neg|is_between, ":eek:ld_faction", kingdoms_begin, kingdoms_end),
  (try_begin),
#Handle separately for adding to the player's faction
#The player may decide to accept or reject the return
(this_or_next|eq, ":faction_liege", "trp_player"),
(eq, ":faction_no", "fac_player_supporters_faction"),
#(eq, 1, 0),#<-- temporarily disable
#Lord comes to petition the player instead of automatically returning
(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
(troop_set_slot, ":troop_no", slot_troop_occupation, slto_inactive),
#Show event (no log without actual faction change)
(str_store_troop_name, s4, ":troop_no"),
(str_store_faction_name, s5, ":faction_no"),
(str_store_troop_name, s6, ":faction_liege"),
(display_message, "@{s4} has returned from exile, seeking refuge with {s6} of {s5}."),
#Remove party
etc
]),
Quick question, but did the vassal returning from exile join your faction or an NPC? It looks like this might be a pretty simple fix, I am pretty sure all you need to do is change the blue slto_inactive to slto_kingdom_hero. However it looks like lords which are members of a faction will be ignored by this code, so though it might start working from this point on it may not fix any of the lords who have already tried to re-spawn. But probably we can make a trigger that will force them back. For now try testing with this small change and see what happens. Remember again to back everything up in case something goes wrong.
I'll right. I'll try this. Hopefully there is an exiled lord in one of my saves so the return will happen and I can check if they're genuinely returned. Might have to do a bit of waiting in game though.

As for which faction... uh... all of them? I am in Swadia, serving Lady Isolla of Suno (overthrew Harlaus). But there are many vassals that have returned to all 6 factions that have disappeared the same way. I believe there were about 120 vassals in the beginning of the game, now there are about 70. Yup, that's about 40 to 50 vassals just... in limbo. The worst part is the game somehow treats them as active vassals so in Swadia, the game treats us as if we have 20 vassals, except 13 of them are missing and only 7 are truly active.

Anyway, you mentioned a trigger to periodically force them back? How would I go about creating a new code for that? Which file will that code go in, module_simple_triggers.py?

I'm going to export the new code and run the game now. Will report back as soon as I have a result.
 
Looks like it didn't work. Managed to get an example.

Image 1: Signore Fraichin being pardoned (2nd last line):
http://i.imgur.com/zqmaKBP.jpg

Image 2: Signore Fraichin's character page stating him being a vassal of the Rhodoks:
http://i.imgur.com/1t7b9Fb.jpg

Image 3: Rhodok page, Signore Fraichin is missing from the list of vassals:
http://i.imgur.com/22RwvbZ.jpg


He's also missing from the list when I went to a Rhodok noble to ask "I want to know the location of someone". Maybe the trigger method would be a simpler solution?

EDIT: Any chance there's a try_end missing, thus nullifying a try_begin section? I'm going to go through the 100 lines again and see how every try_begin gets closed with a try_end. It's a common human error to omit something like this, isn't it?
 
I can't quite see what the script is doing wrong. It's possible that this is actually being caused by something else that is not the slto_ assignment, or something else is resetting it. You can try using this simple trigger, which I haven't tested at all but might work. If this doesn't then perhaps something else is the issue.

Paste this into module_simple_triggers. Doesn't really matter where (as long as it's not the middle of another trigger) but generally the bottom of the file works fine, before the final "]".

Code:
 (24, #Every 24 hours
	[
		(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end), #Search through active NPCs
			(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement), #If they are retired
			(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive), #or if they are inactive
			(store_troop_faction, ":cur_faction", ":troop_no"), #Get their faction
			(is_between, ":cur_faction", kingdoms_begin, kingdoms_end), #If they have a faction
			(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero), #Make them a kingdom hero                     
		(try_end),
	]
 ),

Be sure to wait at least 48 hours (in game of course) just to be sure it is or isn't working. Basically what this should do is find NPCs that are retired or inactive but also belong to a faction. That way Lords that have disappeared but haven't returned yet should be ignored. I also wonder now if we need to call the script create_kingdom_hero_party... Just try this for now and see what happens.
 
Ruthven said:
I can't quite see what the script is doing wrong. It's possible that this is actually being caused by something else that is not the slto_ assignment, or something else is resetting it. You can try using this simple trigger, which I haven't tested at all but might work. If this doesn't then perhaps something else is the issue.

Paste this into module_simple_triggers. Doesn't really matter where (as long as it's not the middle of another trigger) but generally the bottom of the file works fine, before the final "]".

Code:
 (24, #Every 24 hours
	[
		(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end), #Search through active NPCs
			(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement), #If they are retired
			(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive), #or if they are inactive
			(store_troop_faction, ":cur_faction", ":troop_no"), #Get their faction
			(is_between, ":cur_faction", kingdoms_begin, kingdoms_end), #If they have a faction
			(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero), #Make them a kingdom hero                     
		(try_end),
	]
 ),

Be sure to wait at least 48 hours (in game of course) just to be sure it is or isn't working. Basically what this should do is find NPCs that are retired or inactive but also belong to a faction. That way Lords that have disappeared but haven't returned yet should be ignored. I also wonder now if we need to call the script create_kingdom_hero_party... Just try this for now and see what happens.

That didn't work. (EDIT: Waited for 5 days) Damn lol. I'm at a complete loss. Even more so now that from this thread I linked earlier, http://forums.taleworlds.com/index.php?topic=181224.0

the guy had his issue resolved with that one lord when that other guy changed it to slto_kingdom_hero. Seems like your trigger was my best shot at this.. hmm...

EDIT: How come you wrote it to #Search through active NPCs though? A couple of lines later you wrote it to search for inactive NPCs. I'm confused at how this works. Don't those exclude each other?
 
Ah sorry, my comment must have been confusing there. active_npcs is just the name of the constant for all NPCs that can own fiefs, so in Native it includes all lords as well as kings, claimants, and companions. You can try changing this to lords_begin and lords_end but it would probably have the same result.

As a last ditch effort try this:
Code:
(24, #Every 24 hours
	[
		(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end), #Search through active NPCs
			(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement), #If they are retired
			(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive), #or if they are inactive
			(store_troop_faction, ":cur_faction", ":troop_no"), #Get their faction
			(is_between, ":cur_faction", kingdoms_begin, kingdoms_end), #If they have a faction
			(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero), #Make them a kingdom hero 
			(troop_set_note_available, ":troop_no", 1), #Force availability in Notes
			(call_script, "script_create_kingdom_hero_party", ":troop_no", "p_town_16"), #Force spawn at Dhirim
		(try_end),
	]
 ),
This should spawn the kingdom hero party at Dhirim for easy testing.

Actually hold on now. You're compiling the module system after each change right?
 
Ruthven said:
Ah sorry, my comment must have been confusing there. active_npcs is just the name of the constant for all NPCs that can own fiefs, so in Native it includes all lords as well as kings, claimants, and companions. You can try changing this to lords_begin and lords_end but it would probably have the same result.

As a last ditch effort try this:
Code:
(24, #Every 24 hours
	[
		(try_for_range, ":troop_no", active_npcs_begin, active_npcs_end), #Search through active NPCs
			(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement), #If they are retired
			(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive), #or if they are inactive
			(store_troop_faction, ":cur_faction", ":troop_no"), #Get their faction
			(is_between, ":cur_faction", kingdoms_begin, kingdoms_end), #If they have a faction
			(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero), #Make them a kingdom hero 
			(troop_set_note_available, ":troop_no", 1), #Force availability in Notes
			(call_script, "script_create_kingdom_hero_party", ":troop_no", "p_town_16"), #Force spawn at Dhirim
		(try_end),
	]
 ),
This should spawn the kingdom hero party at Dhirim for easy testing.

Actually hold on now. You're compiling the module system after each change right?

Yes sir, compiling after every change, testing, then reporting back results.

Unfortunately, the latest one haven't shown any result as well. Went to Dhirim, waited for 7 days. Checked the castle, I stared at the screen and watched to see if any lords happened to spawn just outside the town, nothing.

Again, not on the faction's list of vassals and not on the list on "I want to know the location of someone".

Afterwards, I went to delete the whole Floris Expanded 2.54 folder and reinstalled. No difference. Anyway, I've deleted Floris Expanded 2.54 and I'm now going to try Floris Evolved. That one was last updated .. well, yesterday. It's still being worked on up to this day. I'm going to start a new save and wait for as long as it takes for vassal to get exiled and then pardoned, and see if it's different in Evolved. I really hope it is.
 
It's bugged there too. LOL.

The Diplomacy mod makers didn't even bother removing the option entirely. Kept it an option for a feature that doesn't work. And the Floris guys couldn't be bothered to remove it all the same. That's a save I've been playing for a couple of months gone. There doesn't seem to be any way of stopping Calradia becoming a deserted land toward the 500+ day late game I guess. No way to prevent exile, no way to reverse exile.

I'm giving up. I was hoping to have a save running up until Bannerlord. Now I'm just hoping Calradia becoming deserted isn't going to be a problem in Bannerlord too.
 
Actually, I think the variable can be edited with this tool: https://forums.taleworlds.com/index.php/topic,295270.0.html

Woulda saved some pain if I'd known about this before. That's probably how the mod creator changed that one fella's savegame file in the first place.
 
Just noticed that the code that was changed was for a player accepting an exiled lord.  The OP tested the fix and noted it did not work, but, in the case he tested was an AI liege accepting the lord. 

I'm not a modder, so I have no idea what I'm doing. 

#Now actually change the faction
(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
(try_begin), #new-begin
(neq, ":faction_no", "fac_player_supporters_faction"),
(this_or_next|troop_slot_eq, ":troop_no", slot_troop_occupation, slto_inactive),
(troop_slot_eq, ":troop_no", slot_troop_occupation, slto_retirement),
(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero),
(try_end), #new-end

#Log event
(str_store_troop_name, s4, ":troop_no"),
(str_store_faction_name, s5, ":faction_no"),
(str_store_troop_name, s6, ":faction_liege"),
(display_log_message, "@{s4} has been granted a pardon by {s6} of {s5} and has returned from exile."),


Can that be changed to:

(call_script, "script_change_troop_faction", ":troop_no", ":faction_no"),
(troop_set_slot, ":troop_no", slot_troop_occupation, slto_kingdom_hero),
#Log event
(str_store_troop_name, s4, ":troop_no"),
(str_store_faction_name, s5, ":faction_no"),
(str_store_troop_name, s6, ":faction_liege"),
(display_log_message, "@{s4} has been granted a pardon by {s6} of {s5} and has returned from exile."),
 
Back
Top Bottom