diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index 5c16ad69..a29126a4 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -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 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; } diff --git a/src/game/boe.combat.cpp b/src/game/boe.combat.cpp index 45b00bb3..d93a044d 100644 --- a/src/game/boe.combat.cpp +++ b/src/game/boe.combat.cpp @@ -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]; } diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 9079b860..58863030 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -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 text_sbar, item_sbar, shop_sbar; std::shared_ptr 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(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"){ diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index c292e5f0..3b29213a 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -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; }