Some refactor of special node system
- Context type (town/out/scen) is now an enum - Don't expose internals in the header - Use a state struct to pass things around through the system - Fix special AFFECT_DEADNESS case for default party selection - Maybe other bits and pieces?
This commit is contained in:
@@ -243,7 +243,8 @@ bool prime_time() {
|
||||
|
||||
static void handle_spellcast(eSkill which_type, bool& did_something, bool& need_redraw, bool& need_reprint) {
|
||||
short store_sp[6];
|
||||
extern short spec_target_type, spec_target_fail;
|
||||
extern short spec_target_fail;
|
||||
extern eSpecCtxType spec_target_type;
|
||||
if(!someone_awake()) {
|
||||
ASB("Everyone's asleep/paralyzed.");
|
||||
need_reprint = true;
|
||||
@@ -574,10 +575,8 @@ static void handle_talk(location destination, bool& did_something, bool& need_re
|
||||
did_something = true;
|
||||
need_redraw = true;
|
||||
if(univ.town.monst[i].special_on_talk >= 0) {
|
||||
short s1, s2, s3;
|
||||
run_special(eSpecCtx::HAIL, 2, univ.town.monst[i].special_on_talk, univ.town.monst[i].cur_loc, &s1, &s2, &s3);
|
||||
if(s3 > 0)
|
||||
need_redraw = true;
|
||||
short s1;
|
||||
run_special(eSpecCtx::HAIL, eSpecCtxType::TOWN, univ.town.monst[i].special_on_talk, univ.town.monst[i].cur_loc, &s1, nullptr, &need_redraw);
|
||||
if(s1 > 0)
|
||||
break;
|
||||
}
|
||||
@@ -1415,11 +1414,9 @@ static void advance_time(bool did_something, bool need_redraw, bool need_reprint
|
||||
// MARK: At this point, see if any specials have been queued up, and deal with them
|
||||
// Note: We just check once here instead of looping because run_special also pulls from the queue.
|
||||
if(!special_queue.empty()) {
|
||||
short s1 = 0, s2 = 0, s3 = 0;
|
||||
pending_special_type pending = special_queue.front();
|
||||
special_queue.pop();
|
||||
run_special(pending, &s1, &s2, &s3);
|
||||
if(s3 > 0) need_redraw = true;
|
||||
run_special(pending, nullptr, nullptr, &need_redraw);
|
||||
}
|
||||
|
||||
// MARK: Handle non-PC stuff (like monsters) if the party actually did something
|
||||
|
@@ -47,7 +47,8 @@ extern short missile_firer,current_monst_tactic;
|
||||
eSpell spell_being_cast;
|
||||
bool spell_freebie;
|
||||
short missile_inv_slot, ammo_inv_slot;
|
||||
short spell_caster, spec_target_type, spec_target_fail, spec_target_options;
|
||||
eSpecCtxType spec_target_type;
|
||||
short spell_caster, spec_target_fail, spec_target_options;
|
||||
short force_wall_position = 10; // 10 -> no force wall
|
||||
bool processing_fields = true;
|
||||
short futzing;
|
||||
@@ -861,11 +862,11 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
|
||||
attacker.restore_sp(before / 3);
|
||||
}
|
||||
} else if(weap.ability == eItemAbil::WEAPON_CALL_SPECIAL) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, target.get_loc().x);
|
||||
univ.party.force_ptr(22, target.get_loc().y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKING_MELEE, 0, weap.abil_data[0],attacker.combat_pos, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKING_MELEE, eSpecCtxType::SCEN, weap.abil_data[0], attacker.combat_pos, &s1);
|
||||
if(s1 > 0)
|
||||
attacker.ap += 4;
|
||||
}
|
||||
@@ -1008,7 +1009,7 @@ void place_target(location target) {
|
||||
}
|
||||
|
||||
void do_combat_cast(location target) {
|
||||
short adjust,r1,r2,level,bonus = 1,dummy;
|
||||
short adjust,r1,r2,level,bonus = 1;
|
||||
snd_num_t store_sound = 0;
|
||||
bool freebie = false,ap_taken = false,cost_taken = false;
|
||||
short num_targets = 1;
|
||||
@@ -1118,12 +1119,13 @@ void do_combat_cast(location target) {
|
||||
draw_terrain(2);
|
||||
}
|
||||
boom_targ[i] = target;
|
||||
bool need_redraw = false;
|
||||
switch(spell_being_cast) {
|
||||
case eSpell::NONE: // Not a spell but a special node targeting
|
||||
r1 = r2 = 0;
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spell_caster, target, &r1, &dummy, &r2);
|
||||
r1 = 0;
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spell_caster, target, &r1, nullptr, &need_redraw);
|
||||
failed = r1;
|
||||
if(r2 > 0) redraw_screen(REFRESH_ALL);
|
||||
if(need_redraw) redraw_screen(REFRESH_ALL);
|
||||
break;
|
||||
case eSpell::GOO: case eSpell::WEB: case eSpell::GOO_BOMB:
|
||||
place_spell_pattern(current_pat,target,FIELD_WEB,univ.cur_pc);
|
||||
@@ -1851,31 +1853,31 @@ void fire_missile(location target) {
|
||||
}
|
||||
} else if(ammo.ability == eItemAbil::WEAPON_CALL_SPECIAL) {
|
||||
// TODO: Should this be checked on the missile as well as on the ammo? (Provided they're different.)
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, victim->get_loc().x);
|
||||
univ.party.force_ptr(22, victim->get_loc().y);
|
||||
univ.party.force_ptr(20, univ.get_target_i(*victim));
|
||||
run_special(eSpecCtx::ATTACKING_RANGE, 0, missile.abil_data[0], missile_firer.combat_pos, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKING_RANGE, eSpecCtxType::SCEN, missile.abil_data[0], missile_firer.combat_pos, &s1);
|
||||
if(s1 > 0)
|
||||
missile_firer.ap += (overall_mode == MODE_FIRING) ? 3 : 2;
|
||||
}
|
||||
if(cCreature* monst = dynamic_cast<cCreature*>(victim)) {
|
||||
if(monst->abil[eMonstAbil::HIT_TRIGGER].active) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, monst->cur_loc.x);
|
||||
univ.party.force_ptr(22, monst->cur_loc.y);
|
||||
univ.party.force_ptr(20, univ.get_target_i(*monst));
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, 0, monst->abil[eMonstAbil::HIT_TRIGGER].special.extra1, missile_firer.combat_pos, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, eSpecCtxType::SCEN, monst->abil[eMonstAbil::HIT_TRIGGER].special.extra1, missile_firer.combat_pos, &s1);
|
||||
if(s1 > 0)
|
||||
missile_firer.ap += (overall_mode == MODE_FIRING) ? 3 : 2;
|
||||
}
|
||||
} else if(cPlayer* pc = dynamic_cast<cPlayer*>(victim)) {
|
||||
if(cInvenSlot spec_item = pc->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, pc->combat_pos.x);
|
||||
univ.party.force_ptr(22, pc->combat_pos.y);
|
||||
univ.party.force_ptr(20, univ.get_target_i(*pc));
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, 0, spec_item->abil_data[0], missile_firer.combat_pos, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, eSpecCtxType::SCEN, spec_item->abil_data[0], missile_firer.combat_pos, &s1);
|
||||
if(s1 > 0)
|
||||
missile_firer.ap += (overall_mode == MODE_FIRING) ? 3 : 2;
|
||||
}
|
||||
@@ -2485,14 +2487,14 @@ void do_monster_turn() {
|
||||
// Unusual ability - don't use multiple times per round
|
||||
if(cur_monst->abil[eMonstAbil::SPECIAL].active && !special_called && party_can_see_monst(i) && get_ran(1,1,1000) <= cur_monst->abil[eMonstAbil::SPECIAL].special.extra3) {
|
||||
uAbility abil = cur_monst->abil[eMonstAbil::SPECIAL];
|
||||
short s1, s2, s3;
|
||||
short s1;
|
||||
special_called = true;
|
||||
univ.party.force_ptr(21, targ_space.x);
|
||||
univ.party.force_ptr(22, targ_space.y);
|
||||
if(target < 6)
|
||||
univ.party.force_ptr(20, 11 + target); // ready to be passed to SELECT_TARGET node
|
||||
else univ.party.force_ptr(20, target); // ready to be passed to SELECT_TARGET node
|
||||
run_special(eSpecCtx::MONST_SPEC_ABIL,0,abil.special.extra1,cur_monst->cur_loc,&s1,&s2,&s3);
|
||||
run_special(eSpecCtx::MONST_SPEC_ABIL, eSpecCtxType::SCEN, abil.special.extra1, cur_monst->cur_loc, &s1);
|
||||
if(s1 <= 0)
|
||||
take_m_ap(abil.special.extra2,cur_monst);
|
||||
}
|
||||
@@ -2942,20 +2944,20 @@ void monster_attack(short who_att,iLiving* target) {
|
||||
|
||||
if(pc_target != nullptr) {
|
||||
if(cInvenSlot spec_item = pc_target->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, target->get_loc().x);
|
||||
univ.party.force_ptr(22, target->get_loc().y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKED_MELEE, 0, spec_item->abil_data[0], attacker->cur_loc, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_MELEE, eSpecCtxType::SCEN, spec_item->abil_data[0], attacker->cur_loc, &s1);
|
||||
if(s1 > 0)
|
||||
attacker->ap += 4;
|
||||
}
|
||||
} else if(m_target != nullptr && m_target->abil[eMonstAbil::HIT_TRIGGER].active) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, target->get_loc().x);
|
||||
univ.party.force_ptr(22, target->get_loc().y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKED_MELEE, 0, m_target->abil[eMonstAbil::HIT_TRIGGER].special.extra1, attacker->cur_loc, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_MELEE, eSpecCtxType::SCEN, m_target->abil[eMonstAbil::HIT_TRIGGER].special.extra1, attacker->cur_loc, &s1);
|
||||
if(s1 > 0)
|
||||
attacker->ap += 4;
|
||||
}
|
||||
@@ -3083,21 +3085,21 @@ void monst_fire_missile(short m_num,short bless,std::pair<eMonstAbil,uAbility> a
|
||||
}
|
||||
if(pc_target != nullptr) {
|
||||
if(cInvenSlot spec_item = pc_target->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
// TODO: This force_ptr...run_special code is almost duplicated in several places; maybe make a call_attack_spec subroutine!
|
||||
univ.party.force_ptr(21, target->get_loc().x);
|
||||
univ.party.force_ptr(22, target->get_loc().y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, 0, spec_item->abil_data[0], univ.town.monst[m_num].cur_loc, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, eSpecCtxType::SCEN, spec_item->abil_data[0], univ.town.monst[m_num].cur_loc, &s1);
|
||||
if(s1 > 0)
|
||||
univ.town.monst[m_num].ap += abil.second.get_ap_cost(abil.first);
|
||||
}
|
||||
} else if(m_target != nullptr && m_target->abil[eMonstAbil::HIT_TRIGGER].active) {
|
||||
short s1,s2,s3;
|
||||
short s1;
|
||||
univ.party.force_ptr(21, m_target->cur_loc.x);
|
||||
univ.party.force_ptr(22, m_target->cur_loc.y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, 0, m_target->abil[eMonstAbil::HIT_TRIGGER].special.extra1, univ.town.monst[m_num].cur_loc, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, eSpecCtxType::SCEN, m_target->abil[eMonstAbil::HIT_TRIGGER].special.extra1, univ.town.monst[m_num].cur_loc, &s1);
|
||||
if(s1 > 0)
|
||||
univ.town.monst[m_num].ap += abil.second.get_ap_cost(abil.first);
|
||||
}
|
||||
|
@@ -361,8 +361,8 @@ void handle_sale(cShopItem item, int i) {
|
||||
if(univ.party.gold < cost)
|
||||
ASB("Not enough gold.");
|
||||
else {
|
||||
short s1, s2, s3;
|
||||
run_special(eSpecCtx::SHOPPING, 0, base_item.item_level, {0,0}, &s1, &s2, &s3);
|
||||
short s1;
|
||||
run_special(eSpecCtx::SHOPPING, eSpecCtxType::SCEN, base_item.item_level, {0,0}, &s1);
|
||||
if(s1 <= 0) {
|
||||
take_gold(cost,false);
|
||||
active_shop.takeOne(i);
|
||||
@@ -657,7 +657,7 @@ static void show_job_bank(int which_bank, std::string title) {
|
||||
}
|
||||
|
||||
void handle_talk_event(location p) {
|
||||
short get_pc,s1 = -1,s2 = -1,s3 = -1;
|
||||
short get_pc,s1 = -1,s2 = -1;
|
||||
char asked[4];
|
||||
|
||||
short a,b,c,d;
|
||||
@@ -1018,24 +1018,24 @@ void handle_talk_event(location p) {
|
||||
break;
|
||||
// TODO: Strings resulting from this don't seem to be recordable; whyever not!?
|
||||
case eTalkNode::CALL_TOWN_SPEC:
|
||||
run_special(eSpecCtx::TALK,2,a,univ.party.town_loc,&s1,&s2,&s3);
|
||||
run_special(eSpecCtx::TALK, eSpecCtxType::TOWN, a, univ.party.town_loc, &s1, &s2);
|
||||
// check s1 & s2 to see if we got diff str, and, if so, munch old strs
|
||||
if((s1 >= 0) || (s2 >= 0)) {
|
||||
save_talk_str1 = s1 >= 0 ? univ.town->spec_strs[s1] : "";
|
||||
save_talk_str2 = s2 >= 0 ? univ.town->spec_strs[s2] : "";
|
||||
}
|
||||
get_strs(save_talk_str1,save_talk_str2,2,s1,s2);
|
||||
get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::TOWN, s1, s2);
|
||||
put_pc_screen();
|
||||
put_item_screen(stat_window);
|
||||
break;
|
||||
case eTalkNode::CALL_SCEN_SPEC:
|
||||
run_special(eSpecCtx::TALK,0,a,univ.party.town_loc,&s1,&s2,&s3);
|
||||
run_special(eSpecCtx::TALK, eSpecCtxType::SCEN, a, univ.party.town_loc, &s1, &s2);
|
||||
// check s1 & s2 to see if we got diff str, and, if so, munch old strs
|
||||
if((s1 >= 0) || (s2 >= 0)) {
|
||||
save_talk_str1 = s1 >= 0 ? univ.scenario.spec_strs[s1] : "";
|
||||
save_talk_str2 = s2 >= 0 ? univ.scenario.spec_strs[s2] : "";
|
||||
}
|
||||
get_strs(save_talk_str1,save_talk_str2,0,s1,s2);
|
||||
get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::SCEN, s1, s2);
|
||||
put_pc_screen();
|
||||
put_item_screen(stat_window);
|
||||
break;
|
||||
|
@@ -218,7 +218,7 @@ void play_see_monster_str(unsigned short m, location monst_loc) {
|
||||
spec = univ.scenario.scen_monsters[m].see_spec;
|
||||
// Then run the special, if any
|
||||
if(spec > -1){
|
||||
queue_special(eSpecCtx::SEE_MONST, 0, spec, monst_loc);
|
||||
queue_special(eSpecCtx::SEE_MONST, eSpecCtxType::SCEN, spec, monst_loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -106,12 +106,12 @@ void equip_item(short pc_num,short item_num) {
|
||||
|
||||
|
||||
void drop_item(short pc_num,short item_num,location where_drop) {
|
||||
short s1, s2, s3 = 0;
|
||||
short s1, s2;
|
||||
int spec = -1;
|
||||
std::string choice;
|
||||
short how_many = 1;
|
||||
cItem item_store;
|
||||
bool take_given_item = true;
|
||||
bool take_given_item = true, need_redraw = false;
|
||||
location loc;
|
||||
|
||||
item_store = univ.party[pc_num].items[item_num];
|
||||
@@ -158,8 +158,8 @@ void drop_item(short pc_num,short item_num,location where_drop) {
|
||||
}
|
||||
if(spec >= 0)
|
||||
while(how_many--)
|
||||
run_special(eSpecCtx::DROP_ITEM, 0, spec, where_drop, &s1, &s2, &s3);
|
||||
if(s3 > 0)
|
||||
run_special(eSpecCtx::DROP_ITEM, eSpecCtxType::SCEN, spec, where_drop, &s1, &s2, &need_redraw);
|
||||
if(need_redraw)
|
||||
draw_terrain(0);
|
||||
}
|
||||
|
||||
@@ -305,7 +305,6 @@ void make_town_hostile() {
|
||||
// Set Attitude node adapted from *i, meant to replace make_town_hostile node
|
||||
void set_town_attitude(short lo,short hi,eAttitude att) {
|
||||
short num;
|
||||
short a[3] = {}; // Dummy values to pass to run_special.
|
||||
|
||||
if(which_combat_type == 0)
|
||||
return;
|
||||
@@ -348,7 +347,7 @@ void set_town_attitude(short lo,short hi,eAttitude att) {
|
||||
// In some towns, doin' this'll getcha' killed.
|
||||
// (Or something else! Killing the party would be the responsibility of whatever special node is called.)
|
||||
if(univ.town.monst.hostile && univ.town->spec_on_hostile >= 0)
|
||||
run_special(eSpecCtx::TOWN_HOSTILE, 2, univ.town->spec_on_hostile, univ.party.town_loc, &a[0], &a[1], &a[2]);
|
||||
run_special(eSpecCtx::TOWN_HOSTILE, eSpecCtxType::TOWN, univ.town->spec_on_hostile, univ.party.town_loc);
|
||||
}
|
||||
|
||||
// TODO: Set town status to "dead"? Could reuse above with magic att (eg -1), or write new function.
|
||||
@@ -625,7 +624,7 @@ void custom_pic_dialog(std::string title, pic_num_t bigpic) {
|
||||
pic_dlg.run();
|
||||
}
|
||||
|
||||
void story_dialog(std::string title, str_num_t first, str_num_t last, int which_str_type, pic_num_t pic, ePicType pt) {
|
||||
void story_dialog(std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt) {
|
||||
cDialog story_dlg("many-str");
|
||||
dynamic_cast<cPict&>(story_dlg["pict"]).setPict(pic, pt);
|
||||
str_num_t cur = first;
|
||||
@@ -638,11 +637,11 @@ void story_dialog(std::string title, str_num_t first, str_num_t last, int which_
|
||||
} else if(clicked == "right") {
|
||||
cur++;
|
||||
}
|
||||
if(which_str_type == 0)
|
||||
if(which_str_type == eSpecCtxType::SCEN)
|
||||
me["str"].setText(univ.scenario.spec_strs[cur]);
|
||||
else if(which_str_type == 1)
|
||||
else if(which_str_type == eSpecCtxType::OUT)
|
||||
me["str"].setText(univ.out->spec_strs[cur]);
|
||||
else if(which_str_type == 2)
|
||||
else if(which_str_type == eSpecCtxType::TOWN)
|
||||
me["str"].setText(univ.town->spec_strs[cur]);
|
||||
return true;
|
||||
}, {"left", "right", "done"});
|
||||
|
@@ -22,7 +22,7 @@ bool show_get_items(std::string titleText, std::vector<cItem*>& itemRefs, short
|
||||
bool display_item(location from_loc,short pc_num,short mode, bool check_container);
|
||||
short custom_choice_dialog(std::array<std::string, 6>& strs,short pic_num,ePicType pic_type,std::array<short, 3>& buttons) ;
|
||||
void custom_pic_dialog(std::string title, pic_num_t bigpic);
|
||||
void story_dialog(std::string title, str_num_t first, str_num_t last, int which_str_type, pic_num_t pic, ePicType pt);
|
||||
void story_dialog(std::string title, str_num_t first, str_num_t last, eSpecCtxType which_str_type, pic_num_t pic, ePicType pt);
|
||||
short get_num_of_items(short max_num);
|
||||
void init_mini_map();
|
||||
void draw_help_dialog_item_buttons(cDialog& dialog,short item);
|
||||
|
@@ -52,7 +52,8 @@ short combat_percent[20] = {
|
||||
short who_cast,which_pc_displayed;
|
||||
eSpell town_spell;
|
||||
extern bool spell_freebie;
|
||||
extern short spec_target_type, spec_target_fail, spec_target_options;
|
||||
extern eSpecCtxType spec_target_type;
|
||||
extern short spec_target_fail, spec_target_options;
|
||||
bool spell_button_active[90];
|
||||
|
||||
extern short fast_bang;
|
||||
@@ -199,8 +200,7 @@ void put_party_in_scen(std::string scen_name) {
|
||||
custom_choice_dialog(univ.scenario.intro_strs, univ.scenario.intro_mess_pic, PIC_SCEN, buttons);
|
||||
j = 6;
|
||||
}
|
||||
short i,j,k;
|
||||
run_special(eSpecCtx::STARTUP, 0, univ.scenario.init_spec, loc(0,0), &i, &j, &k);
|
||||
run_special(eSpecCtx::STARTUP, eSpecCtxType::SCEN, univ.scenario.init_spec, loc(0,0));
|
||||
give_help(1,2);
|
||||
|
||||
// Compatibility flags
|
||||
@@ -1183,7 +1183,8 @@ void do_priest_spell(short pc_num,eSpell spell_num,bool freebie) {
|
||||
|
||||
extern short spell_caster;
|
||||
void cast_town_spell(location where) {
|
||||
short adjust,r1,store;
|
||||
short r1,store;
|
||||
bool need_redraw = false;
|
||||
location loc;
|
||||
ter_num_t ter;
|
||||
|
||||
@@ -1193,11 +1194,11 @@ void cast_town_spell(location where) {
|
||||
(where.y >= univ.town->in_town_rect.bottom)) {
|
||||
add_string_to_buf(" Can't target outside town.");
|
||||
if(town_spell == eSpell::NONE)
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spec_target_fail, where, &r1, &store, &adjust);
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spec_target_fail, where);
|
||||
return;
|
||||
}
|
||||
|
||||
adjust = can_see_light(univ.party.town_loc,where,sight_obscurity);
|
||||
short adjust = can_see_light(univ.party.town_loc,where,sight_obscurity);
|
||||
if(!spell_freebie)
|
||||
univ.party[who_cast].cur_sp -= (*town_spell).cost;
|
||||
ter = univ.town->terrain(where.x,where.y);
|
||||
@@ -1227,9 +1228,8 @@ void cast_town_spell(location where) {
|
||||
add_string_to_buf(" Can't see target.");
|
||||
else switch(town_spell) {
|
||||
case eSpell::NONE: // Not a spell but a special node targeting
|
||||
r1 = store = 0;
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spell_caster, where, &r1, &adjust, &store);
|
||||
if(store > 0) redraw_screen(REFRESH_ALL);
|
||||
run_special(eSpecCtx::TARGET, spec_target_type, spell_caster, where, nullptr, nullptr, &need_redraw);
|
||||
if(need_redraw) redraw_screen(REFRESH_ALL);
|
||||
break;
|
||||
case eSpell::SCRY_MONSTER: case eSpell::CAPTURE_SOUL:
|
||||
if(iLiving* targ = univ.target_there(where, TARG_MONST)) {
|
||||
@@ -1353,14 +1353,15 @@ void cast_town_spell(location where) {
|
||||
|
||||
// TODO: Currently, the node is called before any spell-specific behaviour (eg missiles) occurs.
|
||||
bool cast_spell_on_space(location where, eSpell spell) {
|
||||
short s1 = 0,s2 = 0,s3 = 0;
|
||||
short s1 = 0;
|
||||
|
||||
for(size_t i = 0; i < univ.town->special_locs.size(); i++)
|
||||
if(where == univ.town->special_locs[i]) {
|
||||
bool need_redraw = false;
|
||||
// TODO: Is there a way to skip this condition without breaking compatibility?
|
||||
if(univ.town->specials[univ.town->special_locs[i].spec].type == eSpecType::IF_CONTEXT)
|
||||
run_special(eSpecCtx::TARGET,2,univ.town->special_locs[i].spec,where,&s1,&s2,&s3);
|
||||
if(s3) redraw_terrain();
|
||||
run_special(eSpecCtx::TARGET, eSpecCtxType::TOWN, univ.town->special_locs[i].spec, where, &s1, nullptr, &need_redraw);
|
||||
if(need_redraw) redraw_terrain();
|
||||
return !s1;
|
||||
}
|
||||
if(spell == eSpell::RITUAL_SANCTIFY)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -19,26 +19,9 @@ bool run_stone_circle(short which);
|
||||
void fade_party();
|
||||
void change_level(short town_num,short x,short y);
|
||||
void push_things();
|
||||
void queue_special(eSpecCtx mode, unsigned short which_type, short spec, location spec_loc);
|
||||
void run_special(eSpecCtx which_mode,short which_type,short start_spec,location spec_loc,short *a,short *b,short *redraw);
|
||||
void run_special(pending_special_type spec, short* a, short* b, short* redraw);
|
||||
cSpecial get_node(short cur_spec,short cur_spec_type);
|
||||
void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void setsd(short a,short b,short val);
|
||||
void handle_message(eSpecCtx which_mode,short cur_type,short mess1,short mess2,short*a,short*b,std::string title="",pic_num_t pic=-1,ePicType pt=PIC_SCEN);
|
||||
void get_strs(std::string& str1, std::string& str2,short cur_type,short which_str1,short which_str2) ;
|
||||
void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void rect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
short *next_spec,short *next_spec_type,short *a,short *b,short *redraw);
|
||||
void queue_special(eSpecCtx mode, eSpecCtxType which_type, spec_num_t spec, location spec_loc);
|
||||
void run_special(eSpecCtx which_mode, eSpecCtxType which_type, spec_num_t start_spec, location spec_loc, short* a = nullptr, short* b = nullptr, bool* redraw = nullptr);
|
||||
void run_special(pending_special_type spec, short* a, short* b, bool* redraw);
|
||||
void get_strs(std::string& str1, std::string& str2,eSpecCtxType cur_type,short which_str1,short which_str2);
|
||||
|
||||
void set_campaign_flag(short sdf_a, short sdf_b, short cpf_a, short cpf_b, short str, bool get_send);
|
||||
|
@@ -584,7 +584,7 @@ location end_town_mode(short switching_level,location destination) { // returns
|
||||
|
||||
auto& timers = univ.party.party_event_timers;
|
||||
timers.erase(std::remove_if(timers.begin(), timers.end(), [](const cTimer& t) {
|
||||
return t.node_type == 2;
|
||||
return t.node_type == eSpecCtxType::TOWN;
|
||||
}), timers.end());
|
||||
|
||||
}
|
||||
@@ -651,11 +651,11 @@ location end_town_mode(short switching_level,location destination) { // returns
|
||||
}
|
||||
|
||||
void handle_town_specials(short /*town_number*/, bool town_dead,location /*start_loc*/) {
|
||||
queue_special(eSpecCtx::ENTER_TOWN, 2, town_dead ? univ.town->spec_on_entry_if_dead : univ.town->spec_on_entry, univ.party.town_loc);
|
||||
queue_special(eSpecCtx::ENTER_TOWN, eSpecCtxType::TOWN, town_dead ? univ.town->spec_on_entry_if_dead : univ.town->spec_on_entry, univ.party.town_loc);
|
||||
}
|
||||
|
||||
void handle_leave_town_specials(short /*town_number*/, short which_spec,location /*start_loc*/) {
|
||||
queue_special(eSpecCtx::LEAVE_TOWN, 2, which_spec, univ.party.out_loc);
|
||||
queue_special(eSpecCtx::LEAVE_TOWN, eSpecCtxType::TOWN, which_spec, univ.party.out_loc);
|
||||
}
|
||||
|
||||
bool abil_exists(eItemAbil abil) { // use when outdoors
|
||||
|
Reference in New Issue
Block a user