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
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
attacks. If the target is not a monster, this has no effect.
<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
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
in a random open space near the party. This can be accompanied by one or two messages, if
you wish.

View File

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

View File

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

View File

@@ -14,19 +14,19 @@ Unused
Unused
Special to Jump To
--------------------
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Force Town Entry
Unused
Unused
First part of message
Second part of message
Unused
Unused
Unused
Town to enter
Direction of entry
Unused
X coordinate to enter at (-1 default)
Y coordinate to enter at (-1 default)
Unused
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.stored_pcs.erase(spec.ex1a);
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:
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
break;
@@ -4429,6 +4434,7 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
std::string str1, str2;
cSpecial spec;
location l;
int i;
spec = cur_node;
*next_spec = cur_node.jumpto;
@@ -4457,6 +4463,17 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
*redraw = 1;
*a = 1;
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:
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
break;

View File

@@ -613,7 +613,7 @@ enum class eSpecType {
AFFECT_LEVEL = 91,
AFFECT_MORALE = 92,
AFFECT_SOUL_CRYSTAL = 93,
AFFECT_EQUIPPED = 94,
UNUSED2 = 94,
AFFECT_MONST_TARG = 95,
AFFECT_MONST_ATT = 96,
AFFECT_MONST_STAT = 97,
@@ -703,7 +703,7 @@ enum class eSpecType {
RECT_LOCK = 217,
RECT_UNLOCK = 218,
OUT_MAKE_WANDER = 225,
UNUSED20 = 226,
OUT_FORCE_TOWN = 226,
OUT_PLACE_ENCOUNTER = 227,
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
// j - Choose button to select a quest
// 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
// (terrain, monster, dialog, talk, item, pc, field, boom, missile, status)
static const char*const button_dict[7][11] = {
@@ -472,13 +473,13 @@ static const char*const button_dict[7][11] = {
" ", // unused
" ", // ex2c
}, { // outdoors nodes
" mm", // msg1
" mmm", // msg1
" ", // msg2
" ", // msg3
" ", // pic
" ", // pictype
" ", // ex1a
" ", // ex1b
" T ", // ex1a
" < ", // ex1b
" ", // ex1c
" ", // ex2a
" ", // 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 'j': strt = STRT_QUEST; title = "Select a quest:"; 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 '5': case '6': case '7': case '8': case '9':
choose_string = false;