Fix menu spells calling repeat_cast_ok(). Fix #754.

This may also be a fix for #557
This commit is contained in:
2025-06-02 11:25:27 -05:00
parent 075cdd2f86
commit 309207b063
4 changed files with 54 additions and 35 deletions

View File

@@ -91,7 +91,7 @@ extern short cen_x, cen_y;//,pc_moves[6];
extern eGameMode overall_mode;
extern eItemWinMode stat_window;
extern location to_create;
extern bool All_Done,spell_forced,monsters_going;
extern bool All_Done,spell_forced,spell_recast,monsters_going;
extern bool party_in_memory;
extern sf::View mainView;
extern bool targeting_line_visible;
@@ -100,6 +100,7 @@ extern bool targeting_line_visible;
extern short which_item_page[6];
extern short store_spell_target,pc_casting;
extern eSpell store_mage, store_priest;
extern short store_mage_caster, store_priest_caster;
extern std::vector<int> spec_item_array;
extern cUniverse univ;
extern cCustomGraphics spec_scen_g;
@@ -371,7 +372,7 @@ void handle_spellcast(eSkill which_type, bool& did_something, bool& need_redraw,
extern eSpecCtxType spec_target_type;
// Dual-caster recast hint toggle:
// Change the recast hint to mage if last spell wasn't mage
if(spell_forced && is_combat() && univ.current_pc().last_cast_type != which_type){
if(spell_recast && is_combat() && univ.current_pc().last_cast_type != which_type){
spell_forced = false;
univ.current_pc().last_cast_type = which_type;
need_redraw = true;
@@ -384,6 +385,7 @@ void handle_spellcast(eSkill which_type, bool& did_something, bool& need_redraw,
} else if(overall_mode == MODE_OUTDOORS) {
cast_spell(which_type);
spell_forced = false;
spell_recast = false;
need_reprint = true;
need_redraw = true;
} else if(overall_mode == MODE_TOWN) {
@@ -391,6 +393,7 @@ void handle_spellcast(eSkill which_type, bool& did_something, bool& need_redraw,
store_sp[i] = univ.party[i].cur_sp;
cast_spell(which_type);
spell_forced = false;
spell_recast = false;
need_reprint = true;
need_redraw = true;
for(int i = 0; i < 6; i++)
@@ -1998,22 +2001,40 @@ void handle_menu_spell(eSpell spell_picked) {
}
spell_forced = true;
spell_recast = false;
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)
if(spell_type == eSkill::MAGE_SPELLS){
store_mage = spell_picked;
else store_priest = spell_picked;
if(spell_type == eSkill::MAGE_SPELLS && (*spell_picked).need_select != SELECT_NO) {
if((store_spell_target = select_pc((*spell_picked).need_select == SELECT_ANY ? eSelectPC::ANY : eSelectPC::ONLY_LIVING,"Cast spell on who?")) == 6)
return;
}
else {
if(spell_type == eSkill::PRIEST_SPELLS && (*spell_picked).need_select != SELECT_NO)
if((store_spell_target = select_pc((*spell_picked).need_select == SELECT_ANY ? eSelectPC::ANY : eSelectPC::ONLY_LIVING,"Cast spell on who?")) == 6)
return;
store_mage_caster = pc_casting;
}else{
store_priest = spell_picked;
store_priest_caster = pc_casting;
}
eSelectPC select_type;
switch((*spell_picked).need_select){
case SELECT_ACTIVE:
select_type = eSelectPC::ONLY_LIVING;
// Skip first line of fallthrough
if(false)
case SELECT_ANY:
select_type = eSelectPC::ANY;
// Skip first line of fallthrough
if(false)
case SELECT_DEAD:
select_type = eSelectPC::ONLY_DEAD;
// Skip first line of fallthrough
if(false)
case SELECT_STONE:
select_type = eSelectPC::ONLY_STONE;
store_spell_target = select_pc(select_type, "Cast spell on who?");
if(store_spell_target == 6) return;
break;
default: break;
}
bool did_something = false, need_redraw = false, need_reprint = false;
handle_spellcast(spell_type, did_something, need_redraw, need_reprint, false);
advance_time(did_something, need_redraw, need_reprint);
@@ -3020,7 +3041,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
break;
// Spells (cast/cancel)
case 'M': spell_forced = true; BOOST_FALLTHROUGH;
case 'M': spell_forced = true; spell_recast = true; BOOST_FALLTHROUGH;
case 'm':
if(overall_mode == MODE_SPELL_TARGET || overall_mode == MODE_FANCY_TARGET || overall_mode == MODE_TOWN_TARGET || overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) {
handle_spellcast(eSkill::MAGE_SPELLS, did_something, need_redraw, need_reprint);
@@ -3028,7 +3049,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
}
break;
case 'P': spell_forced = true; BOOST_FALLTHROUGH;
case 'P': spell_forced = true; spell_recast = true; BOOST_FALLTHROUGH;
case 'p':
if(overall_mode == MODE_SPELL_TARGET || overall_mode == MODE_FANCY_TARGET || overall_mode == MODE_TOWN_TARGET || overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) {
handle_spellcast(eSkill::PRIEST_SPELLS, did_something, need_redraw, need_reprint);
@@ -3109,6 +3130,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
break;
}
spell_forced = false;
spell_recast = false;
return are_done;
}

View File

@@ -36,7 +36,7 @@ extern short which_combat_type;
extern eItemWinMode stat_window;
extern location center;
extern short combat_active_pc;
extern bool monsters_going,spell_forced;
extern bool monsters_going,spell_forced,spell_recast;
extern bool flushingInput;
extern eSpell store_mage, store_priest;
extern short store_mage_lev, store_priest_lev,store_item_spell_level;
@@ -4585,7 +4585,7 @@ bool combat_cast_mage_spell() {
if(!spell_forced)
spell_num = pick_spell(univ.cur_pc,eSkill::MAGE_SPELLS, true);
else {
if(!repeat_cast_ok(eSkill::MAGE_SPELLS))
if(spell_recast && !repeat_cast_ok(eSkill::MAGE_SPELLS))
return false;
spell_num = univ.current_pc().last_cast[eSkill::MAGE_SPELLS];
}
@@ -4804,7 +4804,7 @@ bool combat_cast_priest_spell() {
if(!spell_forced)
spell_num = pick_spell(univ.cur_pc,eSkill::PRIEST_SPELLS, true);
else {
if(!repeat_cast_ok(eSkill::PRIEST_SPELLS))
if(spell_recast && !repeat_cast_ok(eSkill::PRIEST_SPELLS))
return false;
spell_num = univ.current_pc().last_cast[eSkill::PRIEST_SPELLS];
}

View File

@@ -55,7 +55,7 @@ using clara::ParseResultType;
bool All_Done = false;
short num_fonts;
bool first_startup_update = true;
bool first_sound_played = false,spell_forced = false;
bool first_sound_played = false,spell_forced = false,spell_recast = false;
bool party_in_memory = false;
std::shared_ptr<cScrollbar> text_sbar, item_sbar, shop_sbar;
std::shared_ptr<cButton> done_btn, help_btn;
@@ -794,7 +794,7 @@ static void replay_action(Element& action) {
}else if(t == "handle_spellcast"){
auto info = info_from_action(action);
eSkill which_type = boost::lexical_cast<eSkill>(info["which_type"]);
spell_forced = str_to_bool(info["spell_forced"]);
spell_forced = spell_recast = str_to_bool(info["spell_forced"]);
handle_spellcast(which_type, did_something, need_redraw, need_reprint);
}else if(t == "handle_target_space"){

View File

@@ -71,7 +71,7 @@ extern eItemWinMode stat_window;
extern eGameMode overall_mode;
extern fs::path progDir;
extern location center;
extern bool spell_forced,boom_anim_active;
extern bool spell_forced,spell_recast,boom_anim_active;
extern eSpell store_mage, store_priest;
extern short store_mage_lev, store_priest_lev;
extern short store_mage_target, store_priest_target;
@@ -481,7 +481,7 @@ void cast_spell(eSkill type) {
if(!spell_forced)
spell = pick_spell(6, type);
else {
if(!repeat_cast_ok(type))
if(spell_recast && !repeat_cast_ok(type))
return;
spell = type == eSkill::MAGE_SPELLS ? store_mage : store_priest;
pc_casting = type == eSkill::MAGE_SPELLS ? store_mage_caster : store_priest_caster;
@@ -1931,21 +1931,18 @@ static void put_spell_list(cDialog& me, const eSkill store_situation) {
static bool pick_spell_caster(cDialog& me, std::string id, const eSkill store_situation, short& last_darkened, short& store_spell) {
short item_hit = id[id.length() - 1] - '1';
// TODO: This visibility check is probably not needed; wouldn't the dialog framework only trigger on visible elements?
if(me[id].isVisible()) {
pc_casting = item_hit;
if(!pc_can_cast_spell(univ.party[pc_casting],cSpell::fromNum(store_situation,store_spell))) {
if(store_situation == eSkill::MAGE_SPELLS)
store_spell = 70;
else store_spell = 70;
store_spell_target = 6;
}
draw_spell_info(me, store_situation,store_spell);
draw_spell_pc_info(me);
put_spell_led_buttons(me, store_situation,store_spell);
put_pc_caster_buttons(me);
put_pc_target_buttons(me, last_darkened);
pc_casting = item_hit;
if(!pc_can_cast_spell(univ.party[pc_casting],cSpell::fromNum(store_situation,store_spell))) {
if(store_situation == eSkill::MAGE_SPELLS)
store_spell = 70;
else store_spell = 70;
store_spell_target = 6;
}
draw_spell_info(me, store_situation,store_spell);
draw_spell_pc_info(me);
put_spell_led_buttons(me, store_situation,store_spell);
put_pc_caster_buttons(me);
put_pc_target_buttons(me, last_darkened);
return true;
}