SP Tutorial Module System Example of using store_repeat_object to create list of options

Users who are viewing this thread

Once upon a time I was experiencing troubles with finding needed arrows with Large Bag modifier. So I decided to make a feature that you give the arrows you want to some NPC, and he assigns this modifier to it for some fee. But how does he know what arrows he should work with? Best way to do this would be creating a dynamic list right in the dialog, where you manually pick the item you want.

Code:
  [anyone|plyr,"ransom_broker_talk",[(eq, "$b9met", 1),],   "I wish to expand some of my quivers.", "quiver_expansion_start",[]],

  [anyone,"quiver_expansion_start",[],   "Alright then. Which one?", "quiver_expansion_choose",[]],

  [anyone|plyr|repeat_for_100,"quiver_expansion_choose", # note that repeat flag is always accompanied by plyr
  [ # conditions bracket is for setting what list you want. Item list, troop list, whatever. It works similar to try_for_range - your conditions determine what should be iterated
  (store_repeat_object, ":obj"), # this thing always goes first so it could create a list
  (lt, ":obj", 4), # repeat_for_100 gives up to 100 options but we may need our own upper bound. This dialog is about one of player's currently equipped quivers, and he can have only 4 so we use lt
  (val_add, ":obj", 0), # somehow I needed this, but it's not guaranteed you will need it as well
  (troop_get_inventory_slot, ":slot", "trp_player", ":obj"), # this line determines we will iterate player weapon slots
  (troop_get_inventory_slot_modifier, reg5, "trp_player", ":obj"),
  (neq, ":slot", -1),
  (item_get_type, ":type", ":slot"),
  (this_or_next|eq, ":type", itp_type_arrows),
  (this_or_next|eq, ":type", itp_type_bolts),
  (this_or_next|eq, ":type", itp_type_thrown),
  (eq, ":type", itp_type_bullets),
  (neq, reg5, imod_large_bag), # after all necessary restrictions we should take object's name, every list option should contain the string register which allow the list to be dynamic
  (str_clear, s2), # clearing the previous name just in case
  (str_store_item_name, s2, ":slot"), # taking the new one
  ],
   "{s2}", "quiver_expansion_confirm",
  [ # consequences bracket is for setting what should happen after you click on any list option
  (store_repeat_object, ":obj"), # this bracket doesn't see values from conditions one. We retrieve them again with some new restrictions
  (val_add, ":obj", 0),
  (str_clear, s2),
  (str_clear, s3),
  (str_clear, s4),
  (troop_get_inventory_slot, ":slot", "trp_player", ":obj"),
  (troop_get_inventory_slot_modifier, reg5, "trp_player", ":obj"),
  (item_get_type, ":type", ":slot"),
  (store_item_value, ":item_price", ":slot"),
  (store_mul, reg6, ":item_price", 3), # we put all our values directly in regs to display them in dialog string, so player can decide whether it's worth the money
  (try_begin), # additional cost for negative modifier
   (eq, reg5, imod_bent),
   (store_mul, reg7, ":item_price", 2),
   (str_store_string, s3, "@ extra {reg7} due to item condition,"),
  (else_try),
   (assign, reg7, 0), # should be 0 otherwise as it gets added to the main cost later
  (try_end),
  (store_add, "$temp_2", reg6, reg7),
  (val_add, "$temp_2", 3000),
  (try_begin), # extra cost for bullets
   (eq, ":type", itp_type_bullets),
   (str_store_string, s4, "@ extra 1000 since it's bullets,"),
   (val_add, "$temp_2", 1000),
  (try_end),
  (assign, reg8, "$temp_2"), # storing cost for the next dialog
  (assign, reg9, ":obj"), # storing weapon slot for the next dialog
  (str_store_item_name, s2, ":slot"), # storing item name for the next dialog
  ]],
 
  [anyone|plyr,"quiver_expansion_choose",[],
  "Never mind.", "ransom_broker_pretalk",[]],

Here is how the system looks like (see code comments). Note how I created "go back" option in the same dialog state - every list needs it, regardless of its composition.

Code:
  [anyone,"quiver_expansion_confirm",[],
   "Expansion of {s2} will cost you {reg6} denars for the item itself,{s3}{s4} and 3000 for my work. The total cost is {reg8} denars.", "quiver_expansion_confirm_plyr",[]],
 
  [anyone|plyr,"quiver_expansion_confirm_plyr",
  [
  (store_troop_gold, ":gold", "trp_player"),
  (ge, ":gold", reg8),
  ],
   "Deal.", "close_window",
  [
  (troop_remove_gold, "trp_player", reg8),
  (troop_set_inventory_slot_modifier, "trp_player", reg9, imod_large_bag),
  (display_message, "@{s2} are expanded! (+15% without rounding)"),
  ]],
 
  [anyone|plyr,"quiver_expansion_confirm_plyr",[],
   "Hmm, sounds too expensive. Let's choose another item.", "quiver_expansion_start",[]],

The values we stored in the main dialog are displayed here until the conversation ends. So, to sum up, for creating a dynamic list, we need to:
  1. Set up a separate dialog state for it and make a "go back" option right away
  2. Add plyr|repeat_for_100 to the dialog flags so our store_repeat_object operation could actually work
  3. Start both brackets with it and determine what it should iterate in first brackets, and what should happen after picking in second ones
  4. Make sure the text of this dialog contains a dynamic string register to visually see what we are picking
  5. Correctly fill that string in conditions bracket
That's all. Happy list creating!
 
Last edited:
Back
Top Bottom