Add two special nodes

- Node to make a monster target a specific PC or monster
- Node to force town entry from outdoors
This commit is contained in:
2015-06-07 01:21:40 -04:00
parent 8272878cea
commit aa5dfe4f69
8 changed files with 53 additions and 22 deletions

View File

@@ -857,6 +857,11 @@ Soul on it, meaning that a random existing monster will be erased if necessary t
room. Multispace monsters, monsters of the Important race, and monsters with the Splits room. Multispace monsters, monsters of the Important race, and monsters with the Splits
special ability will not be recorded.</dd></dd> special ability will not be recorded.</dd></dd>
<dt>Type 95: Affect Monster Target</dt><dd>Changes the monster's current target. If the
target is not a monster, this has no effect.
<dl>
<dt>Extra 1a:</dt><dd>The new target (same as Extra 1b in Select a Target)</dd></dd>
<dt>Type 96: Affect Monster Attack</dt><dd>Changes the strength of one of a monster's <dt>Type 96: Affect Monster Attack</dt><dd>Changes the strength of one of a monster's
attacks. If the target is not a monster, this has no effect. attacks. If the target is not a monster, this has no effect.
<dl> <dl>
@@ -1823,6 +1828,13 @@ special encounter, once done, each node calls the Jump To node.</p>
<dt>Type 225: Make Outdoor Wandering</dt><dd>A group of wandering monsters appears (at one <dt>Type 225: Make Outdoor Wandering</dt><dd>A group of wandering monsters appears (at one
of the designated wandering monster sites).</dd> of the designated wandering monster sites).</dd>
<dt>Type 226: Force Town Entry</dt><dd>The party is immediately placed in the specified town at the specified location.
<dl>
<dt>Mess1, Mess2:</dt><dd>Standard usage.</dd>
<dt>Extra 1a:</dt><dd>The town to enter.</dd>
<dt>Extra 1b:</dt><dd>You can specify a direction here to use one of the preset town entry points. If you do this, leave the location at (-1,-1).</dd>
<dt>Extra 2a, Extra 2b:</dt><dd>The location to place the party at in the town.</dd></dd>
<dt>Type 227: Place Outdoor Encounter</dt><dd>Places a special outdoor wandering encounter <dt>Type 227: Place Outdoor Encounter</dt><dd>Places a special outdoor wandering encounter
in a random open space near the party. This can be accompanied by one or two messages, if in a random open space near the party. This can be accompanied by one or two messages, if
you wish. you wish.

View File

@@ -92,7 +92,7 @@ level
morale morale
soul-crystal soul-crystal
monst-target
monst-attack monst-attack
monst-statistic monst-statistic
statistic statistic
@@ -223,6 +223,6 @@ rect-unlock
make-out-wandering make-out-wandering
force-town
make-out-monst make-out-monst
out-move-party out-move-party

View File

@@ -222,15 +222,15 @@ Unused
Unused Unused
Special to Jump To Special to Jump To
-------------------- --------------------
Unused Node Affect Monster Target
Unused Unused
Unused Unused
Unused First part of message
Unused Second part of message
Unused
Unused Unused
Unused Unused
Unused Unused
New target (0-5 PC, 100+x monster x)
Unused Unused
Unused Unused
Unused Unused

View File

@@ -14,19 +14,19 @@ Unused
Unused Unused
Special to Jump To Special to Jump To
-------------------- --------------------
Unused Node Force Town Entry
Unused Unused
Unused Unused
Unused First part of message
Unused Second part of message
Unused
Unused
Unused
Unused
Unused Unused
Unused Unused
Unused Unused
Town to enter
Direction of entry
Unused Unused
X coordinate to enter at (-1 default)
Y coordinate to enter at (-1 default)
Unused Unused
Special to Jump To Special to Jump To
-------------------- --------------------

View File

@@ -3247,6 +3247,11 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
univ.party[pc_num].main_status -= eMainStatus::SPLIT; univ.party[pc_num].main_status -= eMainStatus::SPLIT;
univ.stored_pcs.erase(spec.ex1a); univ.stored_pcs.erase(spec.ex1a);
break; break;
case eSpecType::AFFECT_MONST_TARG:
if(pc_num < 100) break;
// TODO: Verify this actually works! It's possible the monster ignores this and just recalculates its target each turn.
dynamic_cast<cCreature*>(pc)->target = spec.ex1a;
break;
default: default:
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!"); giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
break; break;
@@ -4429,6 +4434,7 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
std::string str1, str2; std::string str1, str2;
cSpecial spec; cSpecial spec;
location l; location l;
int i;
spec = cur_node; spec = cur_node;
*next_spec = cur_node.jumpto; *next_spec = cur_node.jumpto;
@@ -4457,6 +4463,17 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
*redraw = 1; *redraw = 1;
*a = 1; *a = 1;
break; break;
case eSpecType::OUT_FORCE_TOWN:
l = {spec.ex2a, spec.ex2b};
if(l.x < 0 || l.y < 0 || l.x >= 64 || l.y >= 64)
i = 9;
else if(spec.ex1b == 0) i = 2;
else if(spec.ex1b == 4) i = 0;
else if(spec.ex1b < 4) i = 3;
else i = 1;
if(i == 9) force_town_enter(spec.ex1a, l);
start_town_mode(spec.ex1a, i);
break;
default: default:
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!"); giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
break; break;

View File

@@ -613,7 +613,7 @@ enum class eSpecType {
AFFECT_LEVEL = 91, AFFECT_LEVEL = 91,
AFFECT_MORALE = 92, AFFECT_MORALE = 92,
AFFECT_SOUL_CRYSTAL = 93, AFFECT_SOUL_CRYSTAL = 93,
AFFECT_EQUIPPED = 94, UNUSED2 = 94,
AFFECT_MONST_TARG = 95, AFFECT_MONST_TARG = 95,
AFFECT_MONST_ATT = 96, AFFECT_MONST_ATT = 96,
AFFECT_MONST_STAT = 97, AFFECT_MONST_STAT = 97,
@@ -703,7 +703,7 @@ enum class eSpecType {
RECT_LOCK = 217, RECT_LOCK = 217,
RECT_UNLOCK = 218, RECT_UNLOCK = 218,
OUT_MAKE_WANDER = 225, OUT_MAKE_WANDER = 225,
UNUSED20 = 226, OUT_FORCE_TOWN = 226,
OUT_PLACE_ENCOUNTER = 227, OUT_PLACE_ENCOUNTER = 227,
OUT_MOVE_PARTY = 228, // allow change sector OUT_MOVE_PARTY = 228, // allow change sector
}; };

View File

@@ -396,6 +396,7 @@ std::istream& operator >> (std::istream& in, eSpecType& e) {
// w - Choose button to select main party status effect // w - Choose button to select main party status effect
// j - Choose button to select a quest // j - Choose button to select a quest
// J - Choose button to select a quest status // J - Choose button to select a quest status
// < - Choose button to select a cardinal direction
// 0..9 - Choose button to select a specific type of picture // 0..9 - Choose button to select a specific type of picture
// (terrain, monster, dialog, talk, item, pc, field, boom, missile, status) // (terrain, monster, dialog, talk, item, pc, field, boom, missile, status)
static const char*const button_dict[7][11] = { static const char*const button_dict[7][11] = {
@@ -472,13 +473,13 @@ static const char*const button_dict[7][11] = {
" ", // unused " ", // unused
" ", // ex2c " ", // ex2c
}, { // outdoors nodes }, { // outdoors nodes
" mm", // msg1 " mmm", // msg1
" ", // msg2 " ", // msg2
" ", // msg3 " ", // msg3
" ", // pic " ", // pic
" ", // pictype " ", // pictype
" ", // ex1a " T ", // ex1a
" ", // ex1b " < ", // ex1b
" ", // ex1c " ", // ex1c
" ", // ex2a " ", // ex2a
" ", // ex2b " ", // ex2b

View File

@@ -829,6 +829,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
case 'w': strt = STRT_STATUS; title = "Select status:"; str_adj = 1; break; case 'w': strt = STRT_STATUS; title = "Select status:"; str_adj = 1; break;
case 'j': strt = STRT_QUEST; title = "Select a quest:"; break; case 'j': strt = STRT_QUEST; title = "Select a quest:"; break;
case 'J': strt = STRT_QUEST_STATUS; title = "Select the quest's status:"; break; case 'J': strt = STRT_QUEST_STATUS; title = "Select the quest's status:"; break;
case '<': strt = STRT_DIR; title = "Select the direction:"; break;
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
choose_string = false; choose_string = false;