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:
2020-02-02 19:12:45 -05:00
parent 973b147a3d
commit 86d2574aed
14 changed files with 646 additions and 671 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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"});

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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