A ledger presentation system, that relies on the dynamic array scripts by sphere, conveniently packaged and made modmerger-ready here.
The ledger uses the "Assess Prices" option in market places to track the prices of items the player learns about. The ledger presentation is then sort-able by production town, destination town, item, or estimated profit. It can be trimmed by any of the things it can be sorted by. It also allows the player to specify certain items to ask about in every marketplace, based on their trade skill. A basic note-taking function is also included, though WSE would be required for editing and the like (so that code is not included...as it isn't written yet).
excuse the misspelling of caret, the lack of a subtitle, and the mis-sized buttons...these problems aren't in the code, I just don't have a more current screenshot. the top screenshot is how the current presentation appears
module_presentations in next post
The ledger uses the "Assess Prices" option in market places to track the prices of items the player learns about. The ledger presentation is then sort-able by production town, destination town, item, or estimated profit. It can be trimmed by any of the things it can be sorted by. It also allows the player to specify certain items to ask about in every marketplace, based on their trade skill. A basic note-taking function is also included, though WSE would be required for editing and the like (so that code is not included...as it isn't written yet).


excuse the misspelling of caret, the lack of a subtitle, and the mis-sized buttons...these problems aren't in the code, I just don't have a more current screenshot. the top screenshot is how the current presentation appears
Code:
spt_array = -1
slot_troop_trade_ledger = 155
#sub-array party ID storage as ledger array element:
date_array = 0
town_array = 1
item_array = 2
destination_array = 3
profit_array = 4
num_ledger_sub_arrays = profit_array - date_array + 1
#custom assess items list
custom_assess_begin = num_ledger_sub_arrays
Code:
("game_log_window", 0, "game_log_window", 0, 0, 0, 0, 0, 0, 1, 1, 1),
#if you don't have this defined as a mesh already; it's native, just needs a module_system declaration
Code:
["book_trade_ledger","Merchant's Ledger", [("book_open",0)], itp_type_book, 0, 3500,weight(2)|abundance(100),imodbits_none],
#make sure that the book is within the range of other reference (non-readable) books
##Also, add to the inventory list of the "book_merchant" troops.
Code:
("trade_ledger_create",
[
(store_script_param_1, ":troop"),
(call_script, "script_array_create"),
(assign, ":ledger", reg0),
(party_set_slot, ":ledger", slot_party_type, spt_array),
(str_store_troop_name_plural, s0, ":troop"),
(party_set_name, ":ledger", "@{s0} Trade Ledger Array"), #For DEBUG
(troop_set_slot, ":troop", slot_troop_trade_ledger, ":ledger"),
(try_begin), #Not really needed yet...but maybe eventually
(neq, ":troop", "trp_player"),
(troop_get_slot, ":owner", ":troop", slot_troop_leaded_party),
(gt, ":owner", 0),
(party_is_active, ":owner"),
(call_script, "script_array_set_owner", ":ledger", ":owner"),
(try_end),
(str_clear, s0),
(try_for_range, ":unused", 0, num_ledger_sub_arrays),
(call_script, "script_array_create"),
(call_script, "script_array_pushback", ":ledger", reg0), #Add value at end
(call_script, "script_array_set_owner", reg0, ":ledger"),
(party_set_name, reg0, s0),
(try_end),
(assign, reg0, ":ledger"),
]),
("trade_ledger_write",
[
(store_script_param_1, ":num_entries"),
(store_script_param_2, ":troop"),
(try_begin),
(troop_slot_ge, ":troop", slot_troop_trade_ledger, 1),
(troop_get_slot, ":ledger", ":troop", slot_troop_trade_ledger),
(call_script, "script_cf_array_is_array", ":ledger"),
(else_try),
(call_script, "script_trade_ledger_create", ":troop"),
(assign, ":ledger", reg0),
(try_end),
(call_script, "script_array_get_element", ":ledger", date_array),
(assign, ":date_array", reg0),
(call_script, "script_array_get_element", ":ledger", town_array),
(assign, ":town_array", reg0),
(call_script, "script_array_get_element", ":ledger", item_array),
(assign, ":item_array", reg0),
(call_script, "script_array_get_element", ":ledger", destination_array),
(assign, ":destination_array", reg0),
(call_script, "script_array_get_element", ":ledger", profit_array),
(assign, ":profit_array", reg0),
(store_current_hours, ":cur_hours"),
(assign, ":params_begin", 3), #1 is number of entries, 2 is troop, 3 is first item
(try_for_range, ":unused", 0, ":num_entries"),
(call_script, "script_array_insert", ":date_array", 0, ":cur_hours"),
(call_script, "script_array_insert", ":town_array", 0, "$current_town"),
(store_add, ":params_end", ":params_begin", 3),
(try_for_range, ":param", ":params_begin", ":params_end"),
(store_script_param, ":value", ":param"),
(store_sub, reg1, ":param", ":params_begin"),
(eq, reg1, 0), #Item ID
(call_script, "script_array_insert", ":item_array", 0, ":value"),
(else_try),
(eq, reg1, 1), #Dest Town
(call_script, "script_array_insert", ":destination_array", 0, ":value"),
(else_try),
(eq, reg1, 2), #Profit
(call_script, "script_array_insert", ":profit_array", 0, ":value"),
(try_end), #Item Details Loop
(assign, ":params_begin", ":params_end"),
(try_end), #Entries Loop
]),
("cf_trade_ledger_trim_entries",
[
(store_script_param_1, ":troop"),
(store_script_param_2, ":condition"), #Num of Days, Item, or Town, or Profit Level
(store_script_param, ":trim_type", 3),
(troop_get_slot, ":ledger", ":troop", slot_troop_trade_ledger),
(ge, ":ledger", 1),
(call_script, "script_cf_array_is_array", ":ledger"),
(call_script, "script_array_get_element", ":ledger", date_array),
(assign, ":date_array", reg0),
(call_script, "script_array_get_element", ":ledger", town_array),
(assign, ":town_array", reg0),
(call_script, "script_array_get_element", ":ledger", item_array),
(assign, ":item_array", reg0),
(call_script, "script_array_get_element", ":ledger", destination_array),
(assign, ":destination_array", reg0),
(call_script, "script_array_get_element", ":ledger", profit_array),
(assign, ":profit_array", reg0),
(call_script, "script_array_get_size", ":date_array"),
(assign, ":ledger_length", reg0),
(call_script, "script_array_get_element", ":ledger", ":trim_type"),
(assign, ":target_array", reg0),
(try_begin),
(this_or_next|eq, ":trim_type", date_array),
(eq, ":trim_type", profit_array),
(try_begin),
(eq, ":trim_type", date_array),
(store_current_hours, ":cur_hours"),
(val_mul, ":condition", 24),
(store_sub, ":condition", ":cur_hours", ":condition"),
(val_add, ":condition", 12), #Just to be a bit on the liberal side of keeping entries
(try_end),
(try_for_range_backwards, ":i", 0, ":ledger_length"),
(call_script, "script_cf_array_get_element", ":target_array", ":i"),
(lt, reg0, ":condition"), #older than the cutoff point / less than profit
(call_script, "script_cf_array_remove", ":date_array", ":i"),
(call_script, "script_cf_array_remove", ":town_array", ":i"),
(call_script, "script_cf_array_remove", ":item_array", ":i"),
(call_script, "script_cf_array_remove", ":destination_array", ":i"),
(call_script, "script_cf_array_remove", ":profit_array", ":i"),
(try_end),
(else_try),
(is_between, ":trim_type", town_array, profit_array), #item or prod/demand towns
(try_for_range_backwards, ":i", 0, ":ledger_length"),
(call_script, "script_cf_array_get_element", ":target_array", ":i"),
(eq, reg0, ":condition"), #matches item or town
(call_script, "script_cf_array_remove", ":date_array", ":i"),
(call_script, "script_cf_array_remove", ":town_array", ":i"),
(call_script, "script_cf_array_remove", ":item_array", ":i"),
(call_script, "script_cf_array_remove", ":destination_array", ":i"),
(call_script, "script_cf_array_remove", ":profit_array", ":i"),
(try_end),
(try_end),
(call_script, "script_array_get_size", ":date_array"),
(store_sub, reg0, ":ledger_length", reg0), #Number of Entries Removed
(gt, reg0, 0),
]),
("cf_trade_ledger_custom_assess_item",
[
(store_script_param_1, ":item"),
(store_script_param_2, ":index"),
(try_begin),
(troop_slot_ge, "trp_player", slot_troop_trade_ledger, 1),
(troop_get_slot, ":ledger", "trp_player", slot_troop_trade_ledger),
(call_script, "script_cf_array_is_array", ":ledger"),
(else_try),
(call_script, "script_trade_ledger_create", "trp_player"),
(assign, ":ledger", reg0),
(try_end),
(ge, ":index", custom_assess_begin),
(assign, ":item_added", 0),
(try_begin),
(call_script, "script_cf_array_get_element", ":ledger", ":index"),
(is_between, reg0, trade_goods_begin, trade_goods_end),
(call_script, "script_cf_array_set_element", ":ledger", ":index", ":item"),
(assign, ":item_added", 1),
(else_try),
(call_script, "script_cf_array_insert", ":ledger", ":index", ":item"),
(assign, ":item_added", 1),
(try_end),
(eq, ":item_added", 1),
]),
("cf_trade_ledger_custom_assess_duplicates",
[
#Test for duplication among custom assesment items
(troop_get_slot, ":ledger", "trp_player", slot_troop_trade_ledger),
(ge, ":ledger", 1),
(call_script, "script_cf_array_is_array", ":ledger"),
(assign, ":dupe_removed", 0),
(call_script, "script_get_max_skill_of_player_party", "skl_trade"),
(assign, ":max_skill", reg0),
(val_max, ":max_skill", 1), #at least 1
(val_add, ":max_skill", custom_assess_begin), ##do i need to add another +1?
(try_for_range, ":index", custom_assess_begin, ":max_skill"),
(call_script, "script_cf_array_get_element", ":ledger", ":index"),
(assign, ":item", reg0),
(try_for_range_backwards, ":i", custom_assess_begin, ":max_skill"),
(neq, ":i", ":index"),
(call_script, "script_cf_array_get_element", ":ledger", ":i"),
(eq, reg0, ":item"),
(call_script, "script_cf_array_remove", ":ledger", ":i"),
(assign, ":dupe_removed", 1),
(try_end),
(try_end),
(eq, ":dupe_removed", 1),
]),
Code:
(str_store_party_name, s5, ":best_result_1_town"),
(str_store_string, s3, "@^Buying {s4} here and selling it at {s5} would bring a profit of {reg6} denars per item.{s3}"),
(try_end),
#Trade Ledger Begin
(try_begin),
(gt, ":num_best_results", 0),
(store_item_kind_count, reg0, "itm_book_trade_ledger"),
(ge, reg0, 1),
(assign, ":num_to_write", ":num_best_results"), ##To deal with maximum of 15 script arguments had to break into 2 "write" operations
(val_min, ":num_to_write", 3),
(call_script, "script_trade_ledger_write", ":num_to_write", "trp_player", ":best_result_1_item", ":best_result_1_town", ":best_result_1_profit", ":best_result_2_item", ":best_result_2_town", ":best_result_2_profit", ":best_result_3_item", ":best_result_3_town", ":best_result_3_profit"),
(gt, ":num_best_results", ":num_to_write"),
(store_sub, ":num_to_write", ":num_best_results", ":num_to_write"),
(call_script, "script_trade_ledger_write", ":num_to_write", "trp_player", ":best_result_4_item", ":best_result_4_town", ":best_result_4_profit", ":best_result_5_item", ":best_result_5_town", ":best_result_5_profit"),
(try_end),
(try_begin),
(troop_slot_ge, "trp_player", slot_troop_trade_ledger, 1),
(troop_get_slot, ":ledger", "trp_player", slot_troop_trade_ledger),
(call_script, "script_cf_array_is_array", ":ledger"),
(call_script, "script_array_get_size", ":ledger"),
(gt, reg0, custom_assess_begin), #There are items slotted to assess
(assign, ":ledger_length", reg0),
(try_for_range, ":i", custom_assess_begin, ":ledger_length"),
(call_script, "script_cf_array_get_element", ":ledger", ":i"),
(is_between, reg0, trade_goods_begin, trade_goods_end),
(neq, ":best_result_1_item", reg0),
(neq, ":best_result_2_item", reg0),
(neq, ":best_result_3_item", reg0),
(neq, ":best_result_4_item", reg0),
(neq, ":best_result_5_item", reg0), #Not already included in the standard run of "assess prices"
(assign, ":trade_good", reg0),
#Check if it can be bought
(party_get_slot, ":merchant", "$current_town", slot_town_merchant),
(store_item_kind_count, reg0, ":trade_good", ":merchant"),
(ge, reg0, 1), #The merchant carries it
(store_mul, ":max_iteration", ":num_towns", ":max_skill"),
(val_div, ":max_iteration", 10),
(assign, ":profit", 0),
(assign, ":dest_town", -1),
(try_for_range, ":unused", 0, ":max_iteration"),
(store_random_in_range, ":random_town", towns_begin, towns_end),
(neq, ":random_town", ":dest_town"),
(store_item_value, ":trade_good_price", ":trade_good"),
(assign, "$g_encountered_party", ":org_encountered_party"),
(call_script, "script_game_get_item_buy_price_factor", ":trade_good"),
(store_mul, ":trade_good_buy_price", ":trade_good_price", reg0),
(val_div, ":trade_good_buy_price", 100),
(val_max, ":trade_good_buy_price", 1),
(assign, "$g_encountered_party", ":random_town"),
(call_script, "script_game_get_item_sell_price_factor", ":trade_good"),
(store_mul, ":trade_good_sell_price", ":trade_good_price", reg0),
(val_div, ":trade_good_sell_price", 100),
(val_max, ":trade_good_sell_price", 1),
(store_sub, ":difference", ":trade_good_sell_price", ":trade_good_buy_price"),
(gt, ":difference", ":profit"),
(assign, ":dest_town", ":random_town"),
(assign, ":profit", ":difference"),
(try_end), #Best price loop
(neq, ":dest_town", -1),
(str_store_item_name, s4, ":trade_good"),
(str_store_party_name, s5, ":dest_town"),
(str_store_string, s3, "@^Buying {s4} here and selling it at {s5} would bring a profit of {reg6} denars per item.{s3}"),
(call_script, "script_trade_ledger_write", 1, "trp_player", ":trade_good", ":dest_town", ":profit"),
(try_end), #Custom Item loop
(assign, "$g_encountered_party", ":org_encountered_party"),
(try_end),
#Trade Ledger End
(str_store_string, s2, "@{reg3?You find:{s1} finds} out the following:^{s3}"),
(try_end),
],
Code:
("action_view_trade_ledger",
[
(store_item_kind_count, reg0, "itm_book_trade_ledger"),
(ge, reg0, 1),
#Ensure it has been written to:
(assign, reg60, 0),
(troop_slot_ge, "trp_player", slot_troop_trade_ledger, 1),
(troop_get_slot, ":ledger", "trp_player", slot_troop_trade_ledger),
(call_script, "script_cf_array_is_array", ":ledger"),
(call_script, "script_array_get_element", ":ledger", date_array),
(call_script, "script_array_get_size", reg0),
(ge, reg0, 1),
(assign, reg60, 1),
],"View Your Trade Ledger.",
[
(assign, reg60, 0), #begin in Default view
(start_presentation, "prsnt_trade_ledger_basic"),
]),
("action_view_trade_ledger_denied",
[
#Only show this when the player owns a ledger, but has not written to it yet
(store_item_kind_count, reg0, "itm_book_trade_ledger"),
(ge, reg0, 1),
(eq, reg60, 0), #from above; hasn't been written to
(disable_menu_option),
], "Assess Items to start your Trade Ledger.", []),
module_presentations in next post