Merge the XXX_BLOCK and SANCTIFY special nodes into a single, more versatile IS_CONTEXT node

This commit is contained in:
2014-12-07 00:36:10 -05:00
parent 5ec983ef32
commit 46c3c69bd9
5 changed files with 143 additions and 43 deletions

View File

@@ -1813,7 +1813,7 @@ void sanctify_space(location where)
// TODO: Generalize this for other spells cast on the space
for (i = 0; i < 50; i++)
if (where == univ.town->special_locs[i]) {
if(univ.town->specials[univ.town->spec_id[i]].type == eSpecType::SANCTIFY)
if(univ.town->specials[univ.town->spec_id[i]].type == eSpecType::IF_CONTEXT)
run_special(eSpecCtx::TARGET,2,univ.town->spec_id[i],where,&s1,&s2,&s3);
return;
}

View File

@@ -47,6 +47,7 @@ extern effect_pat_type current_pat;
extern cOutdoors::cWandering store_wandering_special;
extern short pc_marked_damage[6];
extern short monst_marked_damage[60];
extern short spell_being_cast, town_spell;
extern sf::RenderWindow mini_map;
extern bool fast_bang,end_scenario;
//extern short town_size[3];
@@ -2069,30 +2070,6 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
setsd(cur_node.sd1,cur_node.sd2,
((PSD[cur_node.sd1][cur_node.sd2] == 0) ? 1 : 0) );
check_mess = true;break;
case eSpecType::OUT_BLOCK:
if (is_out()) *next_spec = -1;
if ((is_out()) && (spec.ex1a != 0) && (which_mode == eSpecCtx::OUT_MOVE)) {
ASB("Can't go here while outdoors.");
*a = 1;
}
break;
case eSpecType::TOWN_BLOCK:
if (is_town()) *next_spec = -1;
if ((is_town()) && (spec.ex1a != 0) && (which_mode == eSpecCtx::TOWN_MOVE)) {
ASB("Can't go here while in town mode.");
*a = 1;
}
break;
case eSpecType::FIGHT_BLOCK:
if (is_combat()) *next_spec = -1;
if ((is_combat()) && (spec.ex1a != 0) && (which_mode == eSpecCtx::COMBAT_MOVE)) {
ASB("Can't go here during combat.");
*a = 1;
}
break;
case eSpecType::LOOK_BLOCK:
if ((which_mode == eSpecCtx::OUT_LOOK) || (which_mode == eSpecCtx::TOWN_LOOK)) *next_spec = -1;
break;
case eSpecType::CANT_ENTER:
check_mess = true;
if(which_mode == eSpecCtx::OUT_MOVE || which_mode == eSpecCtx::TOWN_MOVE || which_mode == eSpecCtx::COMBAT_MOVE) {
@@ -2169,11 +2146,6 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
giveError("Stuff Done flag out of range.");
else PSD[spec.sd1][spec.sd2] = PSD[spec.ex1a][spec.ex1b];
break;
case eSpecType::SANCTIFY:
// TODO: Generalize this for other spell targeting
if(which_mode != eSpecCtx::TARGET)
*next_spec = spec.ex1b;
break;
case eSpecType::REST:
check_mess = true;
univ.party.age += spec.ex1a;
@@ -2812,6 +2784,113 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
*next_spec = spec.ex1b;
}
break;
case eSpecType::IF_CONTEXT:
// TODO: Test this. In particular, test that the legacy behaviour is correct.
j = -1;
switch(spec.ex1a) {
case 0: // Out move
if(is_out()) {
j = bool(spec.ex1b); // Should block move? 1 = yes, 0 = no
*next_spec = spec.ex1c;
if(j && which_mode == eSpecCtx::OUT_MOVE)
ASB("Can't go here while outdoors.");
}
break;
case 1: // Town move
if(is_town()) {
j = bool(spec.ex1b); // Should block move? 1 = yes, 0 = no
*next_spec = spec.ex1c;
if(j && which_mode == eSpecCtx::TOWN_MOVE)
ASB("Can't go here while in town mode.");
}
break;
case 2: // Combat move
if(is_combat()) {
j = bool(spec.ex1b); // Should block move? 1 = yes, 0 = no
*next_spec = spec.ex1c;
if(j && which_mode == eSpecCtx::COMBAT_MOVE)
ASB("Can't go here during combat.");
}
break;
case 3: // Out look
if(is_out()) {
if(which_mode == eSpecCtx::OUT_LOOK)
*next_spec = spec.ex1c;
}
break;
case 4: // Town look
if(is_town()) {
if(which_mode == eSpecCtx::TOWN_LOOK)
*next_spec = spec.ex1c;
}
break;
case 5: // Enter town
if(which_mode == eSpecCtx::ENTER_TOWN)
*next_spec = spec.ex1c;
break;
case 6: // Leave town
if(which_mode == eSpecCtx::LEAVE_TOWN)
*next_spec = spec.ex1c;
break;
case 7: // Talking
if(which_mode == eSpecCtx::TALK)
*next_spec = spec.ex1c;
break;
case 8: // Use special item
if(which_mode == eSpecCtx::USE_SPEC_ITEM)
*next_spec = spec.ex1c;
break;
case 9: // Town timer
if(which_mode == eSpecCtx::TOWN_TIMER)
*next_spec = -1;
break;
case 10: // Scenario timer
if(which_mode == eSpecCtx::SCEN_TIMER)
*next_spec = spec.ex1c;
else j = 0;
break;
case 11: // Party timer
if(which_mode == eSpecCtx::PARTY_TIMER)
*next_spec = spec.ex1c;
break;
case 12: // Kill monster
if(which_mode == eSpecCtx::KILL_MONST)
*next_spec = spec.ex1c;
break;
case 13: // Start outdoor encounter
if(which_mode == eSpecCtx::OUTDOOR_ENC)
*next_spec = spec.ex1c;
break;
case 14: // Flee outdoor encounter
if(which_mode == eSpecCtx::FLEE_ENCOUNTER)
*next_spec = spec.ex1c;
break;
case 15: // Win outdoor encounter
if(which_mode == eSpecCtx::WIN_ENCOUNTER)
*next_spec = spec.ex1c;
break;
case 16: // Target spell
if(which_mode == eSpecCtx::TARGET) {
// TODO: I'm not quite sure if this covers every way of determining which spell was cast
if(spec.ex1b == -1 || (is_town() && town_spell == spec.ex1b) || (is_combat() && spell_being_cast == spec.ex1b))
*next_spec = spec.ex1c;
}
break;
case 17: // Use space
if(which_mode == eSpecCtx::USE_SPACE)
*next_spec = spec.ex1c;
break;
case 18: // See monster
if(which_mode == eSpecCtx::SEE_MONST)
*next_spec = spec.ex1c;
break;
case 100: // Look (town or out)
if(which_mode == eSpecCtx::OUT_LOOK || which_mode == eSpecCtx::TOWN_LOOK)
*next_spec = spec.ex1c;
break;
}
if(j >= 0) *a = j;
break;
}
if (check_mess == true) {
handle_message(which_mode,cur_spec_type,cur_node.m1,cur_node.m2,a,b);

View File

@@ -550,10 +550,10 @@ enum class eSpecType {
SECRET_PASSAGE = 4,
DISPLAY_SM_MSG = 5,
FLIP_SDF = 6,
OUT_BLOCK = 7,
TOWN_BLOCK = 8,
FIGHT_BLOCK = 9,
LOOK_BLOCK = 10,
UNUSED1 = 7, // formerly OUT_BLOCK
UNUSED2 = 8, // formerly TOWN_BLOCK
UNUSED3 = 9, // formerly FIGHT_BLOCK
UNUSED4 = 10, // formerly LOOK_BLOCK
CANT_ENTER = 11,
CHANGE_TIME = 12,
SCEN_TIMER_START = 13,
@@ -567,7 +567,7 @@ enum class eSpecType {
CALL_GLOBAL = 21,
SET_SDF_ROW = 22,
COPY_SDF = 23,
SANCTIFY = 24,
UNUSED6 = 24, // formerly SANCTIFY
REST = 25,
WANDERING_WILL_FIGHT = 26,
END_SCENARIO = 27,
@@ -638,6 +638,7 @@ enum class eSpecType {
IF_ENOUGH_MAGE_LORE = 153,
IF_TEXT_RESPONSE = 154,
IF_SDF_EQ = 155,
IF_CONTEXT = 156,
MAKE_TOWN_HOSTILE = 170,
TOWN_CHANGE_TER = 171,
TOWN_SWAP_TER = 172,
@@ -703,7 +704,7 @@ inline eSpecCat getNodeCategory(eSpecType node) {
return eSpecCat::ONCE;
if(code >= 80 && code <= 106)
return eSpecCat::AFFECT;
if(code >= 130 && code <= 155)
if(code >= 130 && code <= 156)
return eSpecCat::IF_THEN;
if(code >= 170 && code <= 195)
return eSpecCat::TOWN;

View File

@@ -34,12 +34,6 @@ cSpecial& cSpecial::operator = (legacy::special_node_type& old){
sd1 = old.sd1;
sd2 = old.sd2;
pic = old.pic;
// Large dialogs with 36x36 dialog graphics
if(old.type == 55 || old.type == 58 || old.type == 189)
pic -= 700;
// Large dialogs with monster graphics
else if(old.type == 57 || old.type == 60)
pic -= 400;
m1 = old.m1;
m2 = old.m2;
ex1a = old.ex1a;
@@ -47,6 +41,32 @@ cSpecial& cSpecial::operator = (legacy::special_node_type& old){
ex2a = old.ex2a;
ex2b = old.ex2b;
jumpto = old.jumpto;
// Now apply any needed conversions.
switch(old.type) {
case 55: case 58: case 189: // Large dialogs with 36x36 dialog graphics
pic -= 700;
break;
case 57: case 60: // Large dialogs with monster graphics
pic -= 400;
break;
// TODO: Originally the block nodes supported messages; the new version doesn't.
// (Will probably need to make special nodes a dynamic vector before fixing this.)
case 7: case 8: case 9: case 10: // out, town, combat, look block
type = eSpecType::IF_CONTEXT;
ex1b = ex1a;
if(old.type == 7) ex1a = (int) eSpecCtx::OUT_MOVE;
if(old.type == 8) ex1a = (int) eSpecCtx::TOWN_MOVE;
if(old.type == 9) ex1a = (int) eSpecCtx::COMBAT_MOVE;
if(old.type == 10) ex1a = 100;
break;
case 24: // ritual of sanctification
type = eSpecType::IF_CONTEXT;
ex1c = jumpto;
jumpto = ex1b;
ex1a = (int) eSpecCtx::TARGET;
ex1b = 108; // Spell ID for ritual of sanctification, as seen in cast_town_spell()
break;
}
return *this;
}

View File

@@ -73,7 +73,7 @@ struct initer {
("secret-pass", eSpecType::SECRET_PASSAGE)
("disp-sm-msg", eSpecType::DISPLAY_SM_MSG)
("flip-sdf", eSpecType::FLIP_SDF)
("filter-context", eSpecType::OUT_BLOCK)
("if-context", eSpecType::IF_CONTEXT)
("block-move", eSpecType::CANT_ENTER)
("change-time", eSpecType::CHANGE_TIME)
("start-timer-scen", eSpecType::SCEN_TIMER_START)