Removing companions?

Users who are viewing this thread

Llew2

Cheap ass bum
Count
It should be as easy as commenting them out of module_troops and the corresponding dialogue references in module_scripts and module_strings, but when I do that, the remaining companions dialogues get completely screwed up, with some intros going to the wrong people, etc.

But all I really need to do is make certain ones not appear in taverns. Anyone know how to do this? I tried removing the 'reserved,' tag, but it didn't like then when I built.
 
If I had to guess, it's that either companion_begin & companion_end are messed up or you missed one or more of the five billion companion strings while removing stuff.  They seem to be fond of computing offsets from troop and party IDs.

The easiest way I can think of is hacking up update_companion_candidates_in_taverns and forcing the undesirable NPCs to a city that doesn't have a tavern (Zendar comes to mind if you're not using it).  I'm pretty sure that the code that sticks them in the scene does a slot check on slot_troop_cur_center and matches it with $current_town though I haven't tested it.  My initial thought was to stuff them into scn_the_happy_boar like Kradus, Dranton, and Xerina but update_companion_candidates_in_taverns would probably just randomly stick them back in normal taverns.

 
I don't know how to go about forcing them the ones I don't want to do anything, because there doesn't seem to be a way to change how the game references them. They are collectively called "npc" (which begets companions_begin and companions_end), and there is no way to separate them without further screwing up references and dialogues.

For instance I tried calling one of them "xnpc16" rather than just "npc16", and changed the corresponding IDs of that companion in all the strings, etc., but it still screwed up the dialogues when I got ingame.

Here is the script that defines companions_begin and companions_end:

Code:
       (store_sub, "$number_of_npc_slots", slot_troop_strings_end, slot_troop_intro),

        (try_for_range, ":npc", companions_begin, companions_end),


            (try_for_range, ":slot_addition", 0, "$number_of_npc_slots"),
                (store_add, ":slot", ":slot_addition", slot_troop_intro),

                (store_mul, ":string_addition", ":slot_addition", 16),
                (store_add, ":string", "str_npc1_intro", ":string_addition"), 
                (val_add, ":string", ":npc"),
                (val_sub, ":string", companions_begin),

                (troop_set_slot, ":npc", ":slot", ":string"),
            (try_end),
        (try_end),

And I did try giving them 'no_scene', but it didn't work.
 
I'll give you two possible solutions, neither are pretty depending on how much your code is different than Native.  Both are speculative at best.

Solution 1:  put all your NPCs back and add the following to update_companion_candidates_in_taverns:
("update_companion_candidates_in_taverns",

(try_for_range, ":troop_no", companions_begin, companions_end),
(troop_set_slot, ":troop_no", slot_troop_cur_center, -1),
(troop_slot_eq, ":troop_no", slot_troop_occupation, 0),
(store_random_in_range, ":town_no", towns_begin, towns_end),
(try_begin),
(neg|troop_slot_eq, ":troop_no", slot_troop_home, ":town_no"),
(neg|troop_slot_eq, ":troop_no", slot_troop_first_encountered, ":town_no"),
(troop_set_slot, ":troop_no", slot_troop_cur_center, ":town_no"),
(try_begin),
(eq, "$cheat_mode", 1),
(str_store_troop_name, 4, ":troop_no"),
(str_store_party_name, 5, ":town_no"),
(display_message, "@{s4} is in {s5}"),
(try_end),
(try_end),
(try_end),

# do this for every troop you want to never see again
(troop_set_slot, "trp_npc1", slot_troop_cur_center, "p_zendar"),

]),

Solution 2:  make the counts match which requires hacking up the bit of code you posted:
The problem is that the hardcoded 16 is the number of companions.  They could have done any number of smart things there like subtracting companions_end from companions_begin and using a variable, but they didn't.  In fact, it would have been far easier and more maintainable if they'd done maths on the NPC offsets and indexed off of the first string of each type rather than sucking up 30 slots and doing the trickery you posted.

If you've been super uber careful about removing exactly the strings for the guys you removed, if you change that 16 to the actual number of companions you have, you should be good to go.

(store_sub, "$number_of_npc_slots", slot_troop_strings_end, slot_troop_intro),

(try_for_range, ":npc", companions_begin, companions_end),


(try_for_range, ":slot_addition", 0, "$number_of_npc_slots"),
(store_add, ":slot", ":slot_addition", slot_troop_intro),

(store_sub, ":npc_count", companions_end, companions_begin), # add this line
(store_mul, ":string_addition", ":slot_addition", ":npc_count"), # change this line

(store_add, ":string", "str_npc1_intro", ":string_addition"),
(val_add, ":string", ":npc"),
(val_sub, ":string", companions_begin),

(troop_set_slot, ":npc", ":slot", ":string"),
(try_end),
(try_end),

Still, any number of things could be wrong.  This system is a bit fragile and it has a lot of moving parts that are spread across three files. 

As I'm looking at doing some companion work as my next task, I'll try to repro your error case and see if either/both of the above fixes it.
 
Code:
["npc2","Marnid","Marnid", tf_hero|tf_unmoveable_in_party_window, scn_the_happy_boar|entry(4),reserved, fac_commoners,[itm_linen_tunic,itm_hide_boots,itm_club],str_7|agi_7|int_11|cha_6|level(1),wp(40),knows_merchant_npc|knows_trade_2|knows_weapon_master_1|knows_ironflesh_1|knows_wound_treatment_1|knows_athletics_2|knows_first_aid_1|knows_leadership_1, 0x000000019d004001570b893712c8d28d00000000001dc8990000000000000000],

You could put them in an unused scene. I know that you can spawn Marnid in the Zendar tavern.
 
I commented out Alayen (npc9) and verified that every companion I talked to had broken dialog.  I applied the second solution and the problem went away.  I didn't test the first solution but I suspect that would work as well. 
 
Try approaching from the other side..

If you have one or more companions that you do not want to show up in taverns, then focus on the routine that puts them there.. (see below)

Code:
#script_update_companion_candidates_in_taverns
  # INPUT: none
  # OUTPUT: none
  ("update_companion_candidates_in_taverns",
    [  (try_for_range, ":troop_no", companions_begin, companions_end),
         (troop_set_slot, ":troop_no", slot_troop_cur_center, -1),
         (troop_slot_eq, ":troop_no", slot_troop_occupation, 0),
         (store_random_in_range, ":town_no", towns_begin, towns_end),
         (try_begin),
           (neg|troop_slot_eq, ":troop_no", slot_troop_home, ":town_no"),
           (neg|troop_slot_eq, ":troop_no", slot_troop_first_encountered, ":town_no"),
           (troop_set_slot, ":troop_no", slot_troop_cur_center, ":town_no"),
           (try_begin),
             (eq, "$cheat_mode", 1),
             (str_store_troop_name, 4, ":troop_no"),
             (str_store_party_name, 5, ":town_no"),     
             #(display_message, "@{s4} is in {s5}"),
           (try_end),
         (try_end),
       (try_end),
     ]),

So.. you have some options on how to do this, either you can do it explicitly or you can do it by a system. 

Explicitly is to write a piece of logic that looks for a particular troop ID "(neq,":troop_no","trp_npc_1") for example, and aborts the move if encountered..A little sloppy but workable.

The other approach is to make a system.  Create a troop slots and append to troops to determine if they are able to be moved or not.  Add the troop slot to module_constants.py and assign a 0 if they are movable and a 1 if they are blocked.
Use the following line as an example for the logic to exclude the tavern assignment for the troop in question.
(troop_slot_eq,":troop_no",slot_troop_tavern,0),

In module_scripts.py at the initialization process you define with set slot commands which campions are to be excluded from being in the taverns.

This way, you can keep the complicated dialogue issues in tact, do not have to remove the companion as he never shows up in the game.

Hope that this gives you another way of thinking about this problem.

Best,

saxondragon





 
kt0's solution number one works like a charm. The renegades aren't anywhere in sight, and they weren't able to sabotage the rest of them.  :smile:
 
The number messing up is a specific offset number for the companions. It is here in module_scripts.py.

Code:
        
   (try_for_range, ":npc", companions_begin, companions_end),


            (try_for_range, ":slot_addition", 0, "$number_of_npc_slots"),
                (store_add, ":slot", ":slot_addition", slot_troop_intro),

                (store_mul, ":string_addition", ":slot_addition", 38),     #####This is the number of companion possibilities you have.
                (store_add, ":string", "str_npc1_intro", ":string_addition"), 
                (val_add, ":string", ":npc"),
                (val_sub, ":string", companions_begin),

                (troop_set_slot, ":npc", ":slot", ":string"),
            (try_end),
        (try_end),

mfberg
 
mfberg said:
The number messing up is a specific offset number for the companions. It is here in module_scripts.py.
You can certainly hardcode it like that if you wish, but I'm prone to losing and forgetting such things.  For my solution, all I have to remember is to fill out all the appropriate strings and to make sure that companions_begin and companions_end are correct.  Less things for me to worry about => less things for me to break.

YMMV.
 
Back
Top Bottom