Recast hint for spellcasters

This commit is contained in:
2025-01-18 16:42:16 -06:00
parent c38c79b12b
commit 0ef3ad81d9
6 changed files with 46 additions and 5 deletions

View File

@@ -1850,6 +1850,7 @@ void handle_menu_spell(eSpell spell_picked) {
spell_forced = true;
pc_casting = univ.cur_pc;
univ.current_pc().last_cast[spell_type] = spell_picked;
univ.current_pc().last_cast_type = spell_type;
if(spell_type == eSkill::MAGE_SPELLS)
store_mage = spell_picked;
else store_priest = spell_picked;

View File

@@ -611,8 +611,38 @@ void draw_text_bar() {
}
if((is_combat()) && (univ.cur_pc < 6) && !monsters_going) {
std::ostringstream sout;
sout << univ.current_pc().name << " (ap: " << univ.current_pc().ap << ')';
put_text_bar(sout.str());
cPlayer& current_pc = univ.current_pc();
sout << current_pc.name << " (ap: " << current_pc.ap << ')';
// Spellcasters print a hint for recasting.
// There's not enough space to print 2 hints for dual-casters,
// so just handle the last type cast.
eSkill type = current_pc.last_cast_type;
std::string hint_prefix = "";
std::ostringstream hint_out;
switch(type){
case eSkill::MAGE_SPELLS:
hint_prefix = "M";
break;
case eSkill::PRIEST_SPELLS:
hint_prefix = "P";
break;
// The only other expected value is eSkill::INVALID
default:
break;
}
if(!hint_prefix.empty()){
hint_out << hint_prefix << ": ";
const cSpell& spell = (*current_pc.last_cast[type]);
if(pc_can_cast_spell(current_pc,type) && spell.cost <= current_pc.get_magic()) {
hint_out << "Recast " << spell.name();
}else{
hint_out << "Cannot recast";
}
}
put_text_bar(sout.str(), hint_out.str());
}
if((is_combat()) && (monsters_going))
// Print bar for 1st monster with >0 ap - that is monster that is going
@@ -623,7 +653,7 @@ void draw_text_bar() {
}
}
void put_text_bar(std::string str) {
void put_text_bar(std::string str, std::string right_str) {
text_bar_gworld.setActive(false);
auto& bar_gw = *ResMgr::graphics.get("textbar");
rect_draw_some_item(bar_gw, rectangle(bar_gw), text_bar_gworld, rectangle(bar_gw));
@@ -635,7 +665,11 @@ void put_text_bar(std::string str) {
rectangle to_rect = rectangle(text_bar_gworld);
to_rect.top += 7;
to_rect.left += 5;
to_rect.right -= 5;
win_draw_string(text_bar_gworld, to_rect, str, eTextMode::LEFT_TOP, style);
// Style has to be wrap to get right-alignment
win_draw_string(text_bar_gworld, to_rect, right_str, eTextMode::WRAP, style, true);
to_rect.right -= string_length(right_str, style);
if(!monsters_going) {
sf::Texture& status_gworld = *ResMgr::graphics.get("staticons");

View File

@@ -31,7 +31,7 @@ void redraw_screen(int refresh);
void put_background();
void draw_text_bar();
void refresh_text_bar();
void put_text_bar(std::string str);
void put_text_bar(std::string str, std::string right_str = "");
void draw_terrain(short mode = 0);
void place_trim(short q,short r,location where,ter_num_t ter_type);
void draw_trim(short q,short r,short which_trim,short which_mode);

View File

@@ -1926,6 +1926,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
if(store_situation == eSkill::MAGE_SPELLS && (*picked_spell).need_select == SELECT_NO) {
store_last_cast_mage = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(false);
me.setResult<short>(store_spell);
return true;
@@ -1933,6 +1934,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
if(store_situation == eSkill::PRIEST_SPELLS && (*picked_spell).need_select == SELECT_NO) {
store_last_cast_priest = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(false);
me.setResult<short>(store_spell);
return true;
@@ -1950,6 +1952,7 @@ static bool finish_pick_spell(cDialog& me, bool spell_toast, const short store_s
store_last_cast_mage = pc_casting;
else store_last_cast_priest = pc_casting;
univ.party[pc_casting].last_cast[store_situation] = picked_spell;
univ.party[pc_casting].last_cast_type = store_situation;
me.toast(true);
return true;
}

View File

@@ -149,7 +149,7 @@ static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,st
short total_width = str_to_draw.getLocalBounds().width;
eTextMode mode = options.mode;
if(mode == eTextMode::WRAP && total_width < dest_rect.width())
if(mode == eTextMode::WRAP && total_width < dest_rect.width() && !options.right_align)
mode = eTextMode::LEFT_TOP;
if(mode == eTextMode::LEFT_TOP && str.find('|') != std::string::npos)
mode = eTextMode::WRAP;

View File

@@ -106,6 +106,9 @@ public:
long unique_id;
// transient stuff
std::map<eSkill,eSpell> last_cast = {{ eSkill::MAGE_SPELLS, eSpell::NONE}, { eSkill::PRIEST_SPELLS, eSpell::NONE }};
// There is already a global last_spellcast_type, but that variable is for the whole party.
// This one is per-PC
eSkill last_cast_type = eSkill::INVALID;
location combat_pos;
short parry = 0;
iLiving* last_attacked = nullptr; // Note: Currently this is assigned but never read