diff --git a/root/data/text/english/game/pbs_craft.msg b/root/data/text/english/game/pbs_craft.msg index 4e4947f..3501845 100644 --- a/root/data/text/english/game/pbs_craft.msg +++ b/root/data/text/english/game/pbs_craft.msg @@ -54,10 +54,11 @@ {304}{}{[Time]} {305}{}{Hours: } {306}{}{Minutes: } +{307}{}{%d h %d m} -{400}{}{Created: } -{401}{}{Dismantled: } -{402}{}{ (} +{400}{}{Created: %s (%d). } +{401}{}{Dismantled: %s (%d). } +{402}{}{%d h %d m passed.} {403}{}{ unit(s)). } {404}{}{ h. } {405}{}{ m. passed.} diff --git a/root/data/text/russian/game/pbs_craft.msg b/root/data/text/russian/game/pbs_craft.msg index c6b9827..f16bb8f 100644 --- a/root/data/text/russian/game/pbs_craft.msg +++ b/root/data/text/russian/game/pbs_craft.msg @@ -54,10 +54,11 @@ {304}{}{[Время]} {305}{}{Часов: } {306}{}{Минут: } +{307}{}{%d ч. %d мин.} -{400}{}{Собрано: } -{401}{}{Разобрано: } -{402}{}{ (} +{400}{}{Собрано: %s (%d). } +{401}{}{Разобрано: %s (%d). } +{402}{}{%d ч. %d мин. прошло.} {403}{}{ предмет(ов)). } {404}{}{ ч. } {405}{}{ м. прошло.} diff --git a/scripts_src/_pbs_craft/craft_utils.h b/scripts_src/_pbs_craft/craft_utils.h index 3b86969..c3b08c7 100644 --- a/scripts_src/_pbs_craft/craft_utils.h +++ b/scripts_src/_pbs_craft/craft_utils.h @@ -8,6 +8,7 @@ #define skill_name(x) mstr_skill(100 + x) #define critter_body_type(crit) (proto_data(obj_pid(crit), cr_body_type)) #define critter_can_craft(crit) (critter_body_type(crit) == CR_BODY_BIPED or critter_body_type(crit) == CR_BODY_ROBOTIC) +#define PARTY_DONATE_MAX_DIST 30 pure procedure check_skill_sum(variable crit, variable skills) begin variable @@ -18,7 +19,7 @@ pure procedure check_skill_sum(variable crit, variable skills) begin for (i := 0; i < numSkills; i++) begin total += has_skill(crit, skills[i]); end - return total >= skills[numSkills]; + return 1 if total >= skills[numSkills] else -total; end procedure get_party_member_with_skill(variable skills) begin @@ -26,7 +27,7 @@ procedure get_party_member_with_skill(variable skills) begin variable obj; //craft_debug("search skill "+debug_array_str(skills)+" at least " + level); foreach (obj in party_member_list_critters) begin - if (obj and critter_can_craft(obj) and check_skill_sum(obj, skills)) then begin + if (obj and critter_can_craft(obj) and check_skill_sum(obj, skills) > 0) then begin ret := obj_name(obj);// proto_data(obj_pid, cr_name) end end @@ -50,6 +51,7 @@ end #define ammo_pid_pack_size(pid) get_proto_data(pid, PROTO_AM_PACK_SIZE) #define actual_ammo_count(inven, item, packSize) (obj_is_carrying_obj(inven, item) - 1) * packSize + get_weapon_ammo_count(item) +#define item_pid_pack_size(pid) (ammo_pid_pack_size(pid) if (proto_data(pid, it_type) == item_type_ammo) else 1) procedure obj_is_carrying_bullets_pid(variable invenObj, variable pid) begin variable @@ -106,24 +108,33 @@ procedure remove_bullets_pid(variable invenObj, variable pid, variable quantity) return (numInStack - newInStack); end -procedure party_is_carrying_obj_pid(variable pid) begin +procedure party_member_can_donate_items(variable obj) begin + return obj == dude_obj + or (obj + and obj_is_visible_flag(obj) + and elevation(obj) == elevation(dude_obj) + and tile_distance_objs(dude_obj, obj) <= PARTY_DONATE_MAX_DIST); +end + +procedure party_is_carrying_obj_pid(variable pid, variable returnAmmoCount := false) begin variable sum := 0, isAmmo := proto_data(pid, it_type) == item_type_ammo, obj, num; foreach (obj in party_member_list_all) begin - if (obj and obj_is_visible_flag(obj)) then begin + if (party_member_can_donate_items(obj)) then begin num := obj_is_carrying_bullets_pid(obj, pid) if isAmmo else obj_is_carrying_obj_pid(obj, pid); - if (num > 0) then + if (num > 0) then begin craft_debug(string_format("party_is_carrying_obj_pid(%s): %s has %d", proto_data(pid, it_name), obj_name_proc(obj), num)); - sum += num; + sum += num; + end end end + craft_debug(string_format("party_is_carrying_obj_pid(%s): sum = %d", proto_data(pid, it_name), sum)); // For ammo, we calculate sum in individual bullets but return a number of *full* packs (as if ammo is combined in one inventory) - if (sum > 0 and isAmmo) then + if (sum > 0 and isAmmo and (not returnAmmoCount)) then sum := sum / ammo_pid_pack_size(pid); - craft_debug(string_format("party_is_carrying_obj_pid(%s): sum = %d", proto_data(pid, it_name), sum)); return sum; end @@ -137,7 +148,7 @@ procedure party_remove_items_pid(variable pid, variable quantity) begin craft_debug("party_remove_items_pid(" + proto_data(pid, it_name) + ", " + quantity + ")"); foreach (obj in party_member_list_all) begin - if (obj and obj_is_visible_flag(obj)) then begin + if (party_member_can_donate_items(obj)) then begin partyDistMap[obj] := tile_distance_objs(dude_obj, obj) + 1; // +1 to avoid 0-unset behavior end end diff --git a/scripts_src/_pbs_craft/crafting.h b/scripts_src/_pbs_craft/crafting.h index 8d2b154..3ee59fb 100644 --- a/scripts_src/_pbs_craft/crafting.h +++ b/scripts_src/_pbs_craft/crafting.h @@ -55,6 +55,8 @@ variable begin button_pressed; display_line; + display_cur_str; + num_options; end @@ -65,7 +67,11 @@ end #define has_prev_page (cur_pos > 0) #define has_next_page (cur_pos + ITEMS_PER_SCREEN < items_avail - 1) +#define COLOR_GREEN 0 +#define COLOR_RED 1 +#define COLOR_DARK_GREEN 2 #define SetText_GREEN SetTextColor(0.0, 1.0, 0.0) +#define SetText_DARK_GREEN SetTextColor(0.0, 0.3, 0.0) #define SetText_RED SetTextColor(1.0, 0.0, 0.0) procedure init_crafting; @@ -128,6 +134,10 @@ procedure recipe_is_available(variable recipe) begin return true; end +procedure cur_recipe_batch_size begin + return cur_recipe.qty * item_pid_pack_size(cur_recipe.pid); +end + procedure do_cancel_on begin end @@ -207,6 +217,8 @@ procedure show_crafting_window begin call show_cancel_button("win_btn"); + play_sfx("IB1P1XX1"); + if (craft_cfg.categories == 1) then begin use_categories := true; end else if (craft_cfg.categories == 2) then begin @@ -336,7 +348,7 @@ procedure display_item_options begin call draw_item_pcx; call draw_item_properties; if (max_batch > 0) then SayOption("1. " + mstr_craft(103), batch_one_item); - if (max_batch > 1) then SayOption("2. " + mstr_craft(108) + mstr_craft(110) + (max_batch * cur_recipe.qty) + mstr_craft(111), batch_all_items); + if (max_batch > 1) then SayOption("2. " + mstr_craft(108) + " (" + (max_batch * cur_recipe_batch_size) + ")", batch_all_items); if (max_undo > 0) then SayOption("3. " + mstr_craft(104), undo_one_item); if (max_undo > 1) then SayOption("4. " + mstr_craft(109) + mstr_craft(110) + max_undo + mstr_craft(111), undo_all_items); SayOption("0: "+mstr_craft(102), items_list_mode); @@ -508,7 +520,8 @@ procedure batch_item(variable num) begin end hours := cur_recipe.time * num / 60; mins := cur_recipe.time * num % 60; - display_msg(mstr_craft(400) + proto_data(cur_recipe.pid, it_name) + mstr_craft(402) + (num * cur_recipe.qty) + mstr_craft(403) + hours + mstr_craft(404) + mins + mstr_craft(405)); + 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 batch_ok_mode; end @@ -533,7 +546,8 @@ procedure undo_batch(variable num) begin call party_remove_items_pid(cur_recipe.pid, num * cur_recipe.qty); hours := cur_recipe.time * num / 60; mins := cur_recipe.time * num % 60; - display_msg(mstr_craft(401) + proto_data(cur_recipe.pid, it_name) + mstr_craft(402) + (num * cur_recipe.qty) + mstr_craft(403) + hours + mstr_craft(404) + mins + mstr_craft(405)); + display_msg(string_format(mstr_craft(401), proto_data(cur_recipe.pid, it_name), (num * cur_recipe_batch_size)) + + string_format(mstr_craft(402), hours, mins)); call undo_ok_mode; end @@ -553,81 +567,95 @@ procedure undo_all_items begin call undo_batch(max_undo); end +procedure display_newline(variable num := 1) begin + display_line += 10 * num; + display_cur_str := ""; +end + +procedure display_print(variable text, variable newLine := true, variable color := COLOR_GREEN, variable justify := 0) begin + variable + w := (get_text_width(display_cur_str) if display_cur_str != "" else 0), + x := (20 + w), + width := (270 - w); + if (color == COLOR_DARK_GREEN) then + SetText_DARK_GREEN; + else if (color == COLOR_RED) then + SetText_RED; + else + SetText_GREEN; + + //craft_debug("Format("+text+", x = " + x + ", w = " + width); + //if (width >= 0 or width >= get_text_width(text)) then + Format(text, x, display_line, width, 20, justify); + //else debug_msg("[craft] ! ERROR ! Attempt to display text beyond display area: " + text + ", x = " + x + ", w = " + width); + if (newLine) then begin + display_line += 10; + display_cur_str := ""; + end else + display_cur_str += text; +end + procedure draw_tools_required begin - variable list, hasAny, i, pid, str, hasAll := true; + variable list, hasThis, hasAny, i, pid, str, hasAll := true; craft_debug("draw_tools_required()"); - Format(mstr_craft(300), 25, display_line, 250, 10, justifycenter); - display_line += 10; + call display_print(mstr_craft(300), true, COLOR_GREEN, justifycenter); if (len_array(cur_recipe.tools) > 0) then foreach (list in (cur_recipe.tools)) begin hasAny := false; i := 0; foreach (pid in list) begin - if (party_is_carrying_obj_pid(pid)) then begin - SetText_GREEN; - hasAny := true; - end else begin - SetText_RED; - end + hasThis := party_is_carrying_obj_pid(pid); + hasAny := hasAny or hasThis; str := proto_data(pid, it_name); if (i) then str := mstr_craft(150) + str; - Format(str, 25, display_line, 250, 10, justifyleft); - display_line += 10; + call display_print(str, false, COLOR_GREEN if hasThis else COLOR_RED); + call display_newline; i += 1; end if (not hasAny) then hasAll := false; end else begin - // If no tools needed - display "No". - SetText_GREEN; - Format(mstr_craft(303), 25, display_line, 250, 10, justifyleft); - display_line += 10; + call display_print(mstr_craft(303)); end - display_line += 10; + call display_newline; return hasAll; end procedure draw_skills_required begin - variable list, str, hasAll := true; + variable list, str, partyStr, dudeSkill, hasThis, hasAll := true; craft_debug("draw_skills_required()"); - SetText_GREEN; - Format(mstr_craft(301), 25, display_line, 250, 10, justifycenter); - display_line += 10; + call display_print(mstr_craft(301), true, COLOR_GREEN, justifycenter); if (len_array(cur_recipe.skills) > 0) then foreach (list in (cur_recipe.skills)) begin - if (check_skill_sum(dude_obj, list)) then begin - SetText_GREEN; - str := ""; + dudeSkill := check_skill_sum(dude_obj, list); + if (dudeSkill > 0) then begin + hasThis := true; end else begin // check party members skills - str := get_party_member_with_skill(list) if craft_cfg.use_party else 0; - if (str) then begin - SetText_GREEN; - str := " (" + str + ")"; - end else begin - SetText_RED; - hasAll := false; - str := ""; - end + partyStr := get_party_member_with_skill(list) if craft_cfg.use_party else 0; + hasThis := partyStr != 0; end - Format(skill_names(list) + ": " + list[len_array(list) - 1] + str, 25, display_line, 250, 10, justifyleft); - display_line += 10; + hasAll := hasAll and hasThis; + str := skill_names(list) + ": " + list[len_array(list) - 1]; + if (not hasThis) then + str += " (" + (-dudeSkill) + ")"; + call display_print(str, false, COLOR_GREEN if hasThis else COLOR_RED); + if (partyStr != 0) then + call display_print(" (" + partyStr + ")", false, COLOR_DARK_GREEN); + call display_newline; end else begin // If no skills - display "No". - SetText_GREEN; - Format(mstr_craft(303), 25, display_line, 250, 10, justifyleft); - display_line += 10; + call display_print(mstr_craft(303)); end - display_line += 10; + call display_newline; return hasAll; end procedure draw_components_required begin - variable list, hasAny, i, numBatches, maxGroupBatch, itemData, pid, qty, str, hasAll := true; + variable list, hasAny, i, hasQty, numBatches, maxGroupBatch, itemData, pid, qty, packSize, str, w, + hasAll := true; craft_debug("draw_components_required()"); - SetText_GREEN; - Format(mstr_craft(302), 25, display_line, 250, 10, justifycenter); - display_line += 10; + call display_print(mstr_craft(302), true, COLOR_GREEN, justifycenter); max_batch := 32767; if (len_array(cur_recipe.input) > 0) then foreach (list in (cur_recipe.input)) begin hasAny := false; @@ -635,22 +663,21 @@ procedure draw_components_required begin maxGroupBatch := 0; // maximum number of batches within single OR group foreach itemData in list begin pid := cfg_item_pid(itemData); - qty := cfg_item_qty(itemData); - numBatches := party_is_carrying_obj_pid(pid) / qty; + packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE) + if (proto_data(pid, it_type) == item_type_ammo) + else 1; + qty := cfg_item_qty(itemData) * packSize; + hasQty := party_is_carrying_obj_pid(pid, true); + numBatches := hasQty / qty; if (numBatches > 0) then begin - SetText_GREEN; hasAny := true; - end else begin - SetText_RED; end if (numBatches > maxGroupBatch) then maxGroupBatch := numBatches; - if (proto_data(pid, it_type) == item_type_ammo) then - qty := qty * get_proto_data(pid, PROTO_AM_PACK_SIZE); - str := proto_data(pid, it_name) + ": " + qty; + str := proto_data(pid, it_name) + ": " + qty + " (" + hasQty + ")"; if (i) then str := mstr_craft(150) + str; - Format(str, 25, display_line, 250, 10, justifyleft); - display_line += 10; + call display_print(str, false, COLOR_GREEN if numBatches > 0 else COLOR_RED); + call display_newline; i += 1; end // Restrict the max batch by a group with smallest number of potential batches @@ -659,11 +686,9 @@ procedure draw_components_required begin end else begin // If no components found - display "No". max_batch := 1; // so we can actually produce the thing.. out of thin air? - SetText_GREEN; - Format(mstr_craft(303), 25, display_line, 250, 10, justifyleft); - display_line += 10; + call display_print(mstr_craft(303), true); end - display_line += 10; + call display_newline; return hasAll; end @@ -683,19 +708,18 @@ procedure draw_item_properties begin componentData; display_line := 100; + display_cur_str := ""; pid := cur_recipe.pid; craft_debug("draw_item_properties " + pid); SelectWin("win_dscr"); // Item name - SetText_GREEN; str := proto_data(pid, it_name); - qty := cur_recipe.qty; - if (proto_data(pid, it_type) == item_type_ammo) then - qty := qty * get_proto_data(pid, PROTO_AM_PACK_SIZE); + qty := cur_recipe_batch_size; - if (qty > 1) then str := str + " x" + qty; - Format(str, 25, display_line, 250, 10, justifycenter); - display_line += 30; + call display_print(str, true, COLOR_GREEN, justifycenter); + if (qty > 1) then + call display_print(" x" + qty, true, COLOR_GREEN, justifycenter); + call display_newline(2); hasTools := draw_tools_required; hasSkills := draw_skills_required; @@ -710,16 +734,17 @@ procedure draw_item_properties begin else 0; // Display time required for crafting. - SetText_GREEN; - Format(mstr_craft(304), 25, display_line, 250, 10, justifycenter); - display_line += 10; + call display_print(mstr_craft(304), true, COLOR_GREEN, justifycenter); hours := cur_recipe.time / 60; mins := cur_recipe.time % 60; - Format(mstr_craft(305) + hours, 25, display_line, 250, 10, justifyleft); - display_line += 10; - Format(mstr_craft(306) + mins, 25, display_line, 250, 10, justifyleft); - + call display_print(string_format(mstr_craft(307), hours, mins) + ((" (" + qty + ")") if (max_batch > 1) else "")); + if (max_batch > 1) then begin + mins := cur_recipe.time * max_batch; + hours := mins / 60; + mins := mins % 60; + call display_print(string_format(mstr_craft(307), hours, mins) + " (" + (qty * max_batch) + ")"); + end ShowWin; end diff --git a/scripts_src/_pbs_craft/gl_pbs_craft.ssl b/scripts_src/_pbs_craft/gl_pbs_craft.ssl index cb0ad26..647f06b 100644 --- a/scripts_src/_pbs_craft/gl_pbs_craft.ssl +++ b/scripts_src/_pbs_craft/gl_pbs_craft.ssl @@ -44,6 +44,10 @@ procedure warning_combat begin end end +procedure schedule_show_crafting begin + show_crafting_scheduled := true; + set_global_script_repeat(1); +end procedure keypress_handler begin variable pressed := get_sfall_arg, @@ -55,8 +59,7 @@ procedure keypress_handler begin if combat_is_initialized then call warning_combat; else if (not(get_game_mode) and craft_ui_mode <= MODE_EXIT) then begin - show_crafting_scheduled := true; - set_global_script_repeat(5); + call schedule_show_crafting; end end else if (craft_ui_mode > MODE_EXIT) then begin oldMode := craft_ui_mode; @@ -123,7 +126,7 @@ procedure do_up begin play_sfx(SFX_BUTTON_UP); //call show_crafting_window in 1; // this doesn't work show_crafting_scheduled := true; - set_global_script_repeat(5); + call schedule_show_crafting; end end