From 1702f795cf39bc625c652945e0e2527ca7fc0f86 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Fri, 21 Mar 2025 10:36:57 -0500 Subject: [PATCH] Lockpicking limit choices to pick-holding PCs --- src/game/boe.actions.cpp | 6 ++++- src/game/boe.items.cpp | 57 ++++++++++++++++++++++++++++----------- src/game/boe.items.hpp | 2 ++ src/game/boe.specials.cpp | 2 +- src/game/boe.town.cpp | 2 ++ 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index adafa995..940a24f8 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -864,7 +864,11 @@ void handle_bash_pick(location destination, bool& did_something, bool& need_redr else if(!is_unlockable(destination)) add_string_to_buf(" Wrong terrain type."); else { - short pc = select_pc(eSelectPC::ONLY_LIVING, isBash ? "Who will bash?" : "Who will pick the lock?", isBash ? eSkill::STRENGTH : eSkill::LOCKPICKING); + short pc = select_pc(isBash ? eSelectPC::ONLY_LIVING : eSelectPC::ONLY_CAN_LOCKPICK, isBash ? "Who will bash?" : "Who will pick the lock?", isBash ? eSkill::STRENGTH : eSkill::LOCKPICKING); + // No one can (select_pc prints the message): + if(pc == 8){ + return; + } if(pc == 6) { add_string_to_buf(" Cancelled."); overall_mode = MODE_TOWN; diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index bae7a8cf..41a856f9 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -942,7 +942,7 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo for(short i = 0; i < 6; i++) { std::string n = boost::lexical_cast(i + 1); bool can_pick = true; - std::string disabled_reason = ""; + std::string extra_info = ""; if(univ.party[i].main_status == eMainStatus::ABSENT || univ.party[i].main_status == eMainStatus::FLED) can_pick = false; @@ -954,17 +954,17 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo } if((overall_mode == MODE_COMBAT) && !adjacent(univ.party[univ.cur_pc].combat_pos,univ.party[i].combat_pos)) { can_pick = false; - disabled_reason = "too far away"; + extra_info = "too far away"; break; } BOOST_FALLTHROUGH; case eSelectPC::ONLY_CAN_GIVE: switch(univ.party[i].can_give_item(item_store)){ case eBuyStatus::TOO_HEAVY: - disabled_reason = "item too heavy"; + extra_info = "item too heavy"; if(false) // skip first line of fallthrough case eBuyStatus::NO_SPACE: - disabled_reason = "no item slot"; + extra_info = "no item slot"; can_pick = false; break; default: @@ -974,7 +974,7 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo case eSelectPC::ONLY_LIVING_WITH_ITEM_SLOT: if(!univ.party[i].has_space()){ can_pick = false; - disabled_reason = "no item slot"; + extra_info = "no item slot"; } BOOST_FALLTHROUGH; case eSelectPC::ONLY_LIVING: @@ -985,6 +985,28 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo if(univ.party[i].main_status == eMainStatus::ALIVE) can_pick = false; break; + case eSelectPC::ONLY_CAN_LOCKPICK:{ + if(univ.party[i].main_status != eMainStatus::ALIVE){ + can_pick = false; + break; + } + if(!univ.party[i].has_abil(eItemAbil::LOCKPICKS)){ + can_pick = false; + extra_info = "no picks"; + break; + } + const cInvenSlot& pick_slot = univ.party[i].has_abil_equip(eItemAbil::LOCKPICKS); + if(!pick_slot){ + can_pick = false; + extra_info = "picks not equipped"; + break; + }else{ + const cItem& picks = *pick_slot; + std::string pick_name = picks.name; + if(picks.ident) pick_name = picks.full_name; + extra_info = pick_name + " x " + std::to_string(picks.charges); + } + }break; // Suppress a compiler warning: default: break; @@ -993,25 +1015,30 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo if(highlight_highest != eSkill::INVALID){ selectPc["pc" + n].appendText(" ({{skill}})"); } + if(!extra_info.empty()){ + selectPc["pc" + n].appendText(": " + extra_info); + } + if(highlight_highest != eSkill::INVALID){ + short skill = univ.party[i].skills[highlight_highest]; + pc_skills[i] = skill; + if(skill > highest_skill) highest_skill = skill; + if(skill != last_skill) all_pcs_equal = false; + last_skill = skill; + } if(!can_pick) { selectPc["pick" + n].hide(); - if(disabled_reason.empty()) + if(extra_info.empty()) selectPc["pc" + n].hide(); - else - selectPc["pc" + n].appendText(": " + disabled_reason); } else { - if(highlight_highest != eSkill::INVALID){ - short skill = univ.party[i].skills[highlight_highest]; - pc_skills[i] = skill; - if(skill > highest_skill) highest_skill = skill; - if(skill != last_skill) all_pcs_equal = false; - last_skill = skill; - } any_options = true; } } if(!any_options){ + if(mode == eSelectPC::ONLY_CAN_LOCKPICK){ + ASB(" No one has lockpicks equipped."); + print_buf(); + } return 8; } diff --git a/src/game/boe.items.hpp b/src/game/boe.items.hpp index 44796764..d04ba893 100644 --- a/src/game/boe.items.hpp +++ b/src/game/boe.items.hpp @@ -51,6 +51,8 @@ enum class eSelectPC { ONLY_CAN_GIVE, // Same as the previous, but in combat, only show *adjacent* living PCs who can take the item. ONLY_CAN_GIVE_FROM_ACTIVE, + // Must have lockpicks equipped + ONLY_CAN_LOCKPICK, ONLY_DEAD, }; // Prompt the player to choose a party member. Returns 0-5 for a pc, 6 for cancel, 7 for all, or 8 if no PCs fit the mode's filter. diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index 82143e98..d3f1efa4 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -482,7 +482,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, if(choice == "leave") break; if(choice == "pick"){ - if((door_pc = select_pc(eSelectPC::ONLY_LIVING, "Who will pick the lock?", eSkill::LOCKPICKING)) < 6) + if((door_pc = select_pc(eSelectPC::ONLY_CAN_LOCKPICK, "Who will pick the lock?", eSkill::LOCKPICKING)) < 6) pick_lock(where_check,door_pc); }else{ if((door_pc = select_pc(eSelectPC::ONLY_LIVING, "Who will bash?", eSkill::STRENGTH)) < 6) diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index d60f3603..a07c4fcd 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -1145,6 +1145,8 @@ void pick_lock(location where,short pc_num) { terrain = univ.town->terrain(where.x,where.y); cInvenSlot which_item = univ.party[pc_num].has_abil_equip(eItemAbil::LOCKPICKS); + + // This should no longer ever happen: if(!which_item) { add_string_to_buf(" Need lockpick equipped."); return;