Dynamic game_menu lengths, I'd guess no?

正在查看此主题的用户

Kahsm

Recruit
I was just quickly wondering if there was a way to use loops to make dynamic menu lengths. Considering the conditionals for the menu items are contained in the item, it seems you have to pre-define all the possible options. So I'm guessing the answer is "no", but I thought I'd make sure there were no snazzy tricks.

Just so you know what I'm talking about, if I were making an NPC who could teleport the player to all cities with a reputation over 20 (the reputation is relative to the city the player is in, not the player himself). I would talk to the npc and he'd offer a list of target cities that fit the following criteria:

1. It's not the current city
2. Has a reputation of at least 20 with the town the player is in

This list could be any number of cities long, from 1 up to however many towns I have in my game (22).  But if I added more towns, I wouldn't want to have to find all my dynamic lists and add more menu options.  The only quick hack I could think of was to use the town_begin and town_end constants and an iterating variable in a register to count how many cities I've already looped through, then add a bunch of extra placeholders (up to 25 in my example).

I end up with some extremely ugly code like this:

插入代码块:
[trp_town_1_traveller, "start", [], "Welcome back {playername}.", "choose_gateway_location", []],
  [trp_town_1_traveller, "choose_gateway_location", [(assign,reg1,towns_begin),(assign,reg2,20)], # 20 defined as minimum relation between city's factions.
    "So, where do you wish to gate to?", "choose_gateway_location_opt",[(assign,reg1,towns_begin)]],
  
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #1
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #2
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #3
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #4
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #5
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #6
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #7
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #8
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #9
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #10
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #11
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #12
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #13
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #14
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #15
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #16
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #17
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #18
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #19
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #20
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #21
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #22
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #23
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #24
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [(assign,":iter_town",reg1),(val_add,reg1,1),(is_between,":iter_town",towns_begin,towns_end),(call_script,"script_get_relation_between_parties","$current_town",":iter_town"),(ge,reg0,reg2),(neq,"$current_town",":iter_town"),(str_store_party_name, s1, ":iter_town")], "Take me to {s1} ({reg0})", "close_window", []], #25
  
  [trp_town_1_traveller|plyr, "choose_gateway_location_opt", [], "I'm fine where I am.", "close_window",[]],

(I would probably add some sort of "fight your way out", if you used a friendly city teleporter to enter an unfriendly city. Probably piss off your ally for pissing off their ally too.)
 
No, you can't have dynamic menus.
However, your example is a dialog, not a menu, and you can have dynamic dialogs. Have a look at the repeat_for_* flags in header_dialogs.py and how they're used in some Native dialogs.
 
Oh nifty. Guess that makes sense, I totally forgot about fief granting and such which is about the same and uses repeat parties. Awesome.

Thank you kindly.
 
What cmxchg8b said.

The only way to get fancy with the coding of menu options (use "lazier" coding for lists without repetition) is to use some actual Python around the Module System code.
Take this example from rubik's Custom Commander:
插入代码块:
  ("export_import_npcs", mnf_enable_hot_keys,
   "Please choose a character, then press the C key to view and export or import the chosen character history.^^You choose {reg0?{s0}:none}.",
   "none",
    [
      (assign, reg0, "$g_player_troop"),
      (str_store_troop_name, s0, "$g_player_troop"),
    ],
    [
      ("export_import_back",[],"Go back",
        [
          (assign, "$g_player_troop", "trp_player"),
          (set_player_troop, "$g_player_troop"),
          (jump_to_menu, "mnu_camp_action"),
        ]
      ),
    ]+[("export_import_npc"+str(x+1),
        [
          (store_add, ":dest_npc", "trp_npc1", x),
          (str_store_troop_name, s0, ":dest_npc"),
        ], "{s0}",
        [
          (store_add, ":dest_npc", "trp_npc1", x),
          (assign, "$g_player_troop", ":dest_npc"),
          (set_player_troop, "$g_player_troop"),
        ]) for x in range(0, 8)]+[
      ("export_import_next",[],"Next page", [(jump_to_menu, "mnu_export_import_npcs_2")]),
    ]
  ),
This then creates 8 menu items, one for each companion. You might be able to do the same for towns...but it wouldn't be as straight forward as this example.
 
Actually, menus can be dynamic as well, but it's a little more limited in terms of design approach.

For an example, see the Mod Options system in Blood and Steel.  I swap menu items in and out, instead of doing string-swaps (which is probably evil and lazy but it works).  You could build a game_menu that had 20 items with string reg names and then use logic in the conditions block to determine which ones would be seen and what their names were, I suspect.  To the end-user, it would look and act like a dynamic menu.

I guess that doesn't count as "truly dynamic", but meh, in most cases it would be fine.
 
后退
顶部 底部