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)) else if(!is_unlockable(destination))
add_string_to_buf(" Wrong terrain type."); add_string_to_buf(" Wrong terrain type.");
else { 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) { if(pc == 6) {
add_string_to_buf(" Cancelled."); add_string_to_buf(" Cancelled.");
overall_mode = MODE_TOWN; 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++) { for(short i = 0; i < 6; i++) {
std::string n = boost::lexical_cast<std::string>(i + 1); std::string n = boost::lexical_cast<std::string>(i + 1);
bool can_pick = true; 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) if(univ.party[i].main_status == eMainStatus::ABSENT || univ.party[i].main_status == eMainStatus::FLED)
can_pick = false; 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)) { if((overall_mode == MODE_COMBAT) && !adjacent(univ.party[univ.cur_pc].combat_pos,univ.party[i].combat_pos)) {
can_pick = false; can_pick = false;
disabled_reason = "too far away"; extra_info = "too far away";
break; break;
} }
BOOST_FALLTHROUGH; BOOST_FALLTHROUGH;
case eSelectPC::ONLY_CAN_GIVE: case eSelectPC::ONLY_CAN_GIVE:
switch(univ.party[i].can_give_item(item_store)){ switch(univ.party[i].can_give_item(item_store)){
case eBuyStatus::TOO_HEAVY: case eBuyStatus::TOO_HEAVY:
disabled_reason = "item too heavy"; extra_info = "item too heavy";
if(false) // skip first line of fallthrough if(false) // skip first line of fallthrough
case eBuyStatus::NO_SPACE: case eBuyStatus::NO_SPACE:
disabled_reason = "no item slot"; extra_info = "no item slot";
can_pick = false; can_pick = false;
break; break;
default: default:
@@ -974,7 +974,7 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo
case eSelectPC::ONLY_LIVING_WITH_ITEM_SLOT: case eSelectPC::ONLY_LIVING_WITH_ITEM_SLOT:
if(!univ.party[i].has_space()){ if(!univ.party[i].has_space()){
can_pick = false; can_pick = false;
disabled_reason = "no item slot"; extra_info = "no item slot";
} }
BOOST_FALLTHROUGH; BOOST_FALLTHROUGH;
case eSelectPC::ONLY_LIVING: 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) if(univ.party[i].main_status == eMainStatus::ALIVE)
can_pick = false; can_pick = false;
break; 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: // Suppress a compiler warning:
default: default:
break; break;
@@ -993,25 +1015,30 @@ short select_pc(eSelectPC mode, std::string title, eSkill highlight_highest, boo
if(highlight_highest != eSkill::INVALID){ if(highlight_highest != eSkill::INVALID){
selectPc["pc" + n].appendText(" ({{skill}})"); 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) { if(!can_pick) {
selectPc["pick" + n].hide(); selectPc["pick" + n].hide();
if(disabled_reason.empty()) if(extra_info.empty())
selectPc["pc" + n].hide(); selectPc["pc" + n].hide();
else
selectPc["pc" + n].appendText(": " + disabled_reason);
} else { } 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; any_options = true;
} }
} }
if(!any_options){ if(!any_options){
if(mode == eSelectPC::ONLY_CAN_LOCKPICK){
ASB(" No one has lockpicks equipped.");
print_buf();
}
return 8; return 8;
} }

View File

@@ -51,6 +51,8 @@ enum class eSelectPC {
ONLY_CAN_GIVE, ONLY_CAN_GIVE,
// Same as the previous, but in combat, only show *adjacent* living PCs who can take the item. // Same as the previous, but in combat, only show *adjacent* living PCs who can take the item.
ONLY_CAN_GIVE_FROM_ACTIVE, ONLY_CAN_GIVE_FROM_ACTIVE,
// Must have lockpicks equipped
ONLY_CAN_LOCKPICK,
ONLY_DEAD, 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. // 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") if(choice == "leave")
break; break;
if(choice == "pick"){ 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); pick_lock(where_check,door_pc);
}else{ }else{
if((door_pc = select_pc(eSelectPC::ONLY_LIVING, "Who will bash?", eSkill::STRENGTH)) < 6) 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); terrain = univ.town->terrain(where.x,where.y);
cInvenSlot which_item = univ.party[pc_num].has_abil_equip(eItemAbil::LOCKPICKS); cInvenSlot which_item = univ.party[pc_num].has_abil_equip(eItemAbil::LOCKPICKS);
// This should no longer ever happen:
if(!which_item) { if(!which_item) {
add_string_to_buf(" Need lockpick equipped."); add_string_to_buf(" Need lockpick equipped.");
return; return;