Lockpicking limit choices to pick-holding PCs

This commit is contained in:
2025-03-21 10:36:57 -05:00
parent 629d92601f
commit 1702f795cf
5 changed files with 52 additions and 17 deletions

View File

@@ -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;

View File

@@ -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<std::string>(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,13 +1015,9 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo
if(highlight_highest != eSkill::INVALID){
selectPc["pc" + n].appendText(" ({{skill}})");
}
if(!can_pick) {
selectPc["pick" + n].hide();
if(disabled_reason.empty())
selectPc["pc" + n].hide();
else
selectPc["pc" + n].appendText(": " + disabled_reason);
} else {
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;
@@ -1007,11 +1025,20 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo
if(skill != last_skill) all_pcs_equal = false;
last_skill = skill;
}
if(!can_pick) {
selectPc["pick" + n].hide();
if(extra_info.empty())
selectPc["pc" + n].hide();
} else {
any_options = true;
}
}
if(!any_options){
if(mode == eSelectPC::ONLY_CAN_LOCKPICK){
ASB(" No one has lockpicks equipped.");
print_buf();
}
return 8;
}

View File

@@ -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.

View File

@@ -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)

View File

@@ -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;