diff --git a/docs/todo.txt b/docs/todo.txt index 1172cfe..04b0e28 100644 --- a/docs/todo.txt +++ b/docs/todo.txt @@ -5,9 +5,6 @@ for 0.9.*: for "future": - add early game Flamerthrower (Incinerator) - Stimpak & Healing powder heal amt to depend upon First Aid skill -- Crafting: use items from party members inventory -- Crafting: read config from INI file and texts from game/craft.msg -- Crafting: add small XP rewards for crafting - add tie-ins to barter "demand" feature, have some trader explain it in dialog (and maybe also boost your barter skill) - replace "handmade grenade" sprite - replace Throwing Axe sprite diff --git a/root/data/config/pbs_craft.ini b/root/data/config/pbs_craft.ini index 93c0ad5..ab05a91 100644 --- a/root/data/config/pbs_craft.ini +++ b/root/data/config/pbs_craft.ini @@ -7,6 +7,10 @@ categories=2 use_gvars=1 ; Crafting shortcut: Ctrl+C hotkey=29+46 +; craft exp multiplier (base is maximum of all averages of required skills) +exp_skill_mult=2.0 +; experience points granted are rounded up to this number (e.g. 1 becomes 5, 13 becomes 15, etc.) +exp_round_to=5 diff --git a/root/data/text/english/game/pbs_craft.msg b/root/data/text/english/game/pbs_craft.msg index 3501845..e6ae91f 100644 --- a/root/data/text/english/game/pbs_craft.msg +++ b/root/data/text/english/game/pbs_craft.msg @@ -62,3 +62,5 @@ {403}{}{ unit(s)). } {404}{}{ h. } {405}{}{ m. passed.} + +{420}{}{You gain %d experience points for creating a new item.} diff --git a/root/data/text/russian/game/pbs_craft.msg b/root/data/text/russian/game/pbs_craft.msg index f16bb8f..e3a6bcd 100644 --- a/root/data/text/russian/game/pbs_craft.msg +++ b/root/data/text/russian/game/pbs_craft.msg @@ -62,3 +62,5 @@ {403}{}{ предмет(ов)). } {404}{}{ ч. } {405}{}{ м. прошло.} + +{420}{}{Вы получаете очки опыта (+%d) за успешную сборку нового предмета.} diff --git a/scripts_src/_pbs_craft/craft_config.h b/scripts_src/_pbs_craft/craft_config.h index 0aa3511..2e5d307 100644 --- a/scripts_src/_pbs_craft/craft_config.h +++ b/scripts_src/_pbs_craft/craft_config.h @@ -3,6 +3,7 @@ #include "../sfall/sfall.h" #include "../sfall/lib.arrays.h" +#include "../sfall/lib.math.h" #include "../sfall/lib.strings.h" variable @@ -56,6 +57,7 @@ end #define cfg_item_qty(itemData) (itemData / 0x10000) #define cfg_parse_int_def(cfg, ini, name, def) cfg.name := atoi(ini.name) if ini.name else def +#define cfg_parse_def_clamp(parseFn, cfg, ini, name, def, min, max) cfg.name := math_clamp(parseFn(ini.name) if ini.name else def, min, max) procedure load_crafting_config begin variable @@ -66,6 +68,8 @@ procedure load_crafting_config begin cfg_parse_int_def(cfg, iniMain, use_party, 0); cfg_parse_int_def(cfg, iniMain, categories, 0); cfg_parse_int_def(cfg, iniMain, use_gvars, 0); + cfg_parse_def_clamp(atof, cfg, iniMain, exp_skill_mult, 0.0, 0.0, 10.0); + cfg_parse_def_clamp(atoi, cfg, iniMain, exp_round_to, 1, 1, 100); craft_debug("crafting cfg main: " + debug_array_str(cfg)); diff --git a/scripts_src/_pbs_craft/craft_utils.h b/scripts_src/_pbs_craft/craft_utils.h index c3b08c7..78497bd 100644 --- a/scripts_src/_pbs_craft/craft_utils.h +++ b/scripts_src/_pbs_craft/craft_utils.h @@ -45,6 +45,20 @@ pure procedure skill_names(variable skills) begin return str; end +procedure recipe_max_average_skill(variable recipe) begin + variable list, skill, skillAvg, numSkills, i, + maxAvg := 0; + if (len_array(recipe.skills) > 0) then foreach (list in (recipe.skills)) begin + numSkills := len_array(list) - 1; + if (numSkills >= 1) then begin + skillAvg := list[numSkills] / numSkills; + if (skillAvg > maxAvg) then + maxAvg = skillAvg; + end + end + return maxAvg; +end + procedure obj_name_proc(variable obj) begin return obj_name(obj) if obj else "(null)"; end diff --git a/scripts_src/_pbs_craft/crafting.h b/scripts_src/_pbs_craft/crafting.h index 3ee59fb..1673c39 100644 --- a/scripts_src/_pbs_craft/crafting.h +++ b/scripts_src/_pbs_craft/crafting.h @@ -32,6 +32,7 @@ #define MAX_CATEGORIES (ITEMS_PER_SCREEN + 2) #define EXTRA_MSG_NAME "pbs_craft.msg" +#define EXP_MAP_NAME "pbs_craft_exp" #define pcx_path(name) "pcx\\" #name ".pcx" @@ -39,6 +40,7 @@ variable begin craft_msg_id; craft_ui_mode; use_categories := false; + craft_exp_map; // maps output item PID to 1 if exp was granted for crafting cur_recipe; cur_category; @@ -114,6 +116,7 @@ procedure init_crafting begin craft_msg_id := add_extra_msg_file(EXTRA_MSG_NAME); craft_ui_mode := MODE_EXIT; craft_raw_cfg := load_raw_crafting_config; + craft_exp_map := load_create_array_map(EXP_MAP_NAME); end @@ -138,6 +141,22 @@ procedure cur_recipe_batch_size begin return cur_recipe.qty * item_pid_pack_size(cur_recipe.pid); end +procedure gain_exp_for_crafting begin + variable + skillMult := craft_cfg.exp_skill_mult, + pid := cur_recipe.pid; + if (skillMult <= 0 or craft_exp_map[pid] > 0) then return; + + variable + skillMaxAvg := recipe_max_average_skill(cur_recipe), + roundTo := craft_cfg.exp_round_to, + exp := ceil(skillMaxAvg * skillMult * 1.0 / roundTo) * roundTo; + + give_exp_points(exp); + display_msg(sprintf(mstr_craft(420), exp)); + craft_exp_map[pid] := 1; +end + procedure do_cancel_on begin end @@ -158,7 +177,6 @@ procedure do_cancel_up begin play_sfx("IB1LU1X1"); call exit_mode; SayQuit; - //tap_key(DIK_ESCAPE); // a hack to close the dialog without actually clicking on any reply options end procedure show_cancel_button(variable winName) begin @@ -522,6 +540,8 @@ procedure batch_item(variable num) begin mins := cur_recipe.time * num % 60; display_msg(string_format(mstr_craft(400), proto_data(cur_recipe.pid, it_name), (num * cur_recipe_batch_size)) + string_format(mstr_craft(402), hours, mins)); + + call gain_exp_for_crafting; call batch_ok_mode; end