Add several new Affect nodes.
- Alter monster statistics on the fly, including basic attacks - Alter experience level and morale (the latter currently only works on monsters while the former might have strange results on PCs) - Alter the contents of the player's soul crystal - Forced Give node now has an option to force-equip the item
This commit is contained in:
@@ -224,9 +224,13 @@ no room in their inventory.
|
||||
<dt>Mess1, Mess2:</dt><dd>Standard usage.</dd>
|
||||
<dt>Extra 1a:</dt><dd>The number of the item to give. Press the Choose button to pick an
|
||||
item.</dd>
|
||||
<dt>Extra 2b:</dt><dd>The special to jump to if the item is not successfully given (if all
|
||||
the parties item slots are full). If No Special is given, the Jump To special is used as
|
||||
<dt>Extra 1b:</dt><dd>The special to jump to if the item is not successfully given (if all
|
||||
the party's item slots are full). If No Special is given, the Jump To special is used as
|
||||
usual.</dd>
|
||||
<dt>Extra 2a:</dt><dd>If 1, the item is given pre-equipped, without checking to see if
|
||||
this is legal. This should only be used if you know exactly what else they have equipped,
|
||||
for example if you are creating a joined NPC or if you previously stripped them of their
|
||||
items.</dd>
|
||||
<dt>Uses:</dt><dd>If you want the party to get an item after winning a combat outdoors,
|
||||
use a Forced Give. This makes sure that if it is at all possible, they get it.</dd>
|
||||
<dt>Uses 2:</dt><dd>Use this is the party is given an item during a talking special
|
||||
@@ -826,6 +830,52 @@ one.</dd></dd>
|
||||
<dl>
|
||||
<dt>Mess3:</dt><dd>The number of the string containing the new name.</dd></dd>
|
||||
|
||||
<dt>Type 91: Affect Level</dt><dd>Alters the experience level of a monster or PC.
|
||||
<dl>
|
||||
<dt>Extra 1a:</dt><dd>The number of levels to add/remove.</dd>
|
||||
<dt>Extra 1b:</dt><dd>If 0, gains levels. Otherwise, removes.</dd>
|
||||
<dt>Note:</dt>Use sparingly, especially when draining. If affecting a PC, this does not
|
||||
change skill points or amount of experience.</dd>
|
||||
|
||||
<dt>Type 92: Affect Morale</dt><dd>Changes a monster's morale. If the target is not a
|
||||
monster, this has no effect. Decreasing morale is the same as a Fear spell.
|
||||
<dl>
|
||||
<dt>Extra 1a:</dt><dd>The amount to increase/decrease morale.</dd>
|
||||
<dt>Extra 1b: If 0, increases. Otherwise, decreases.</dd></dd>
|
||||
|
||||
<dt>Type 95: Affect Soul Crystal</dt><dd>Records the currently targeted monster in the
|
||||
party's soul crystal, or erases it if there is already a monster of the same kind recorded.
|
||||
If the current target is not a monster, this has no effect. If you know the type of the
|
||||
monster you want to record, then you need to first place one on the map, record it in the
|
||||
soul crystal, and finally remove it from the map.
|
||||
<dl>
|
||||
<dt>Extra 1a:</dt><dd>If 0, records. Otherwise, erases.</dd>
|
||||
<dt>Extra 1b:</dt><dd>If 0, the monster is given a chance to resist. If 1, the capture is
|
||||
forced.</dd>
|
||||
<dt>Note:</dt><dd>Recording a monster works exactly as a successful casting of Capture
|
||||
Soul on it, meaning that a random existing monster will be erased if necessary to make
|
||||
room. Multispace monsters, monsters of the Important race, and monsters with the Splits
|
||||
special ability will not be recorded.</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>
|
||||
<dt>Extra 1a:</dt><dd>The attack to change. (Range 0 ... 2)</dd>
|
||||
<dt>Extra 1b:</dt><dd>The amount to change the number of dice. (0 to leave it
|
||||
unchanged.)</dd>
|
||||
<dt>Extra 1c:</dt><dd>The amount to change the number of sides. (0 to leave it
|
||||
unchanged.)</dd>
|
||||
<dt>Extra 2a:</dt><dd>If 0, increase strength. Otherwise, decrease.</dd></dd>
|
||||
|
||||
<dt>Type 97: Affect Monster Statistic</dt><dd>Changes one of a monster's inherent
|
||||
statistics. If the target is not a monster, this has no effect.
|
||||
<dl>
|
||||
<dt>Extra 1a:</dt><dd>The amount to increase/decrease. (Range 0 ... 7)</dd>
|
||||
<dt>Extra 1b:</dt><dd>If 0, increase. Otherwise, decrease.</dd>
|
||||
<dt>Extra 2a:</dt><dd>The statistic to increase/decrease: 0 - max health, 1 - max magic,
|
||||
2 - armor, 3 - skill, 4 - speed, 5 - mage spells, 6 - priest spells, 7 - magic resistance,
|
||||
8 - fire resistance, 9 - cold resistance, 10 - poison resistance</dd></dd>
|
||||
|
||||
<dt>Type 98: Affect Statistic</dt><dd>Changes the character's statistics (e.g. Strength,
|
||||
Mage Spells, etc.)
|
||||
<dl>
|
||||
@@ -1480,7 +1530,7 @@ the party in.</dd>
|
||||
sector (Range 0 ... 47, 0 ... 47)</dd>
|
||||
<dt>Uses:</dt><dd>If, when the party leaves at the north end of a dungeon, you want them
|
||||
to be in a different location in the outdoors from where they were when the entered, place
|
||||
a special node of this type just before the north exit (where theyre forced to step on
|
||||
a special node of this type just before the north exit (where they're forced to step on
|
||||
it).</dd>
|
||||
<dt>Note:</dt><dd>When this node is called, there is a delay while the new outdoors
|
||||
section is loaded into memory. Try not to call it too often.</dd></dd>
|
||||
|
@@ -1066,12 +1066,14 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon
|
||||
return can_enter;
|
||||
}
|
||||
|
||||
void record_monst(cCreature *which_m) {
|
||||
void record_monst(cCreature* which_m, bool forced) {
|
||||
short r1;
|
||||
|
||||
r1 = get_ran(1,1,100);
|
||||
r1 = (r1 * 7) / 10;
|
||||
|
||||
if(forced) r1 = 0;
|
||||
|
||||
if((which_m->x_width > 1) || (which_m->y_width > 1)) {
|
||||
ASB("Capture Soul: Monster is too big.");
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ bool town_move_monster(short num,location dest);
|
||||
bool monster_placid(short m_num);
|
||||
void monst_inflict_fields(short which_monst);
|
||||
bool monst_check_special_terrain(location where_check,short mode,short which_monst);
|
||||
void record_monst(cCreature *which_m);
|
||||
void record_monst(cCreature* which_m, bool forced=false);
|
||||
short place_monster(mon_num_t which,location where,bool forced=false);
|
||||
bool summon_monster(mon_num_t which,location where,short duration,short given_attitude,bool by_party);
|
||||
void activate_monsters(short code,short attitude);
|
||||
|
@@ -2200,7 +2200,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
break;
|
||||
case eSpecType::FORCED_GIVE:
|
||||
check_mess = true;
|
||||
if(!univ.party.forced_give(spec.ex1a,eItemAbil::NONE) && spec.ex1b >= 0)
|
||||
if(!univ.party.forced_give(spec.ex1a + 10000 * spec.ex2a,eItemAbil::NONE) && spec.ex1b >= 0)
|
||||
*next_spec = spec.ex1b;
|
||||
break;
|
||||
case eSpecType::BUY_ITEMS_OF_TYPE:
|
||||
@@ -3001,6 +3001,63 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
else univ.party[i].skills[skill] = minmax(0, skill_max[skill], univ.party[i].skills[skill] + adj);
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_LEVEL:
|
||||
if(pc_num >= 100) {
|
||||
int lvl = pc->get_level();
|
||||
if(spec.ex1b == 0)
|
||||
lvl += spec.ex1a;
|
||||
else lvl -= spec.ex1a;
|
||||
dynamic_cast<cCreature*>(pc)->level = lvl;
|
||||
} else for(i = 0; i < 6; i++)
|
||||
if(pc_num == 6 || pc_num == i) {
|
||||
int cur = univ.party[i].get_level();
|
||||
int lvl = cur;
|
||||
if(spec.ex1b == 0)
|
||||
lvl += spec.ex1a;
|
||||
else lvl -= spec.ex1a;
|
||||
univ.party[i].level = lvl;
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_MORALE:
|
||||
pc->scare(spec.ex1a * (spec.ex1b != 0 ? 1 : -1));
|
||||
break;
|
||||
case eSpecType::AFFECT_MONST_ATT:
|
||||
if(pc_num < 100) break;
|
||||
if(spec.ex1a < 0 || spec.ex1a > 2) {
|
||||
giveError("Invalid monster attack (0-2)");
|
||||
break;
|
||||
}
|
||||
if(spec.ex2a == 0) {
|
||||
dynamic_cast<cCreature*>(pc)->a[spec.ex1a].dice += spec.ex1b;
|
||||
dynamic_cast<cCreature*>(pc)->a[spec.ex1a].dice += spec.ex1c;
|
||||
} else {
|
||||
dynamic_cast<cCreature*>(pc)->a[spec.ex1a].dice -= spec.ex1b;
|
||||
dynamic_cast<cCreature*>(pc)->a[spec.ex1a].dice -= spec.ex1c;
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_MONST_STAT:
|
||||
if(pc_num < 100) break;
|
||||
if(spec.ex2a < 0 || spec.ex2a > 7) {
|
||||
giveError("Invalid monster stat (0-7)");
|
||||
break;
|
||||
}
|
||||
i = spec.ex1a;
|
||||
if(spec.ex1b > 0)
|
||||
i = -i;
|
||||
switch(spec.ex2a) {
|
||||
case 0: dynamic_cast<cCreature*>(pc)->m_health += i; break;
|
||||
case 1: dynamic_cast<cCreature*>(pc)->max_mp += i; break;
|
||||
case 2: dynamic_cast<cCreature*>(pc)->armor += i; break;
|
||||
case 3: dynamic_cast<cCreature*>(pc)->skill += i; break;
|
||||
case 4: dynamic_cast<cCreature*>(pc)->speed += i; break;
|
||||
case 5: dynamic_cast<cCreature*>(pc)->mu += i; break;
|
||||
case 6: dynamic_cast<cCreature*>(pc)->cl += i; break;
|
||||
case 7: dynamic_cast<cCreature*>(pc)->magic_res += i; break;
|
||||
case 8: dynamic_cast<cCreature*>(pc)->fire_res += i; break;
|
||||
case 9: dynamic_cast<cCreature*>(pc)->cold_res += i; break;
|
||||
case 10:dynamic_cast<cCreature*>(pc)->poison_res += i; break;
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_MAGE_SPELL:
|
||||
if(pc_num >= 100) break;
|
||||
if(spec.ex1a != minmax(0,61,spec.ex1a)) {
|
||||
@@ -3042,6 +3099,15 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
}
|
||||
univ.party.alchemy[spec.ex1a] = true;
|
||||
break;
|
||||
case eSpecType::AFFECT_SOUL_CRYSTAL:
|
||||
if(pc_num < 100) break;
|
||||
if(spec.ex1a == 0)
|
||||
record_monst(dynamic_cast<cCreature*>(pc), spec.ex1b);
|
||||
else for(i = 0; i < 4; i++) {
|
||||
if(univ.party.imprisoned_monst[i] == dynamic_cast<cCreature*>(pc)->number)
|
||||
univ.party.imprisoned_monst[i] = 0;
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_PARTY_STATUS:
|
||||
if(spec.ex2a < 0 || spec.ex2a > 3) break;
|
||||
if(spec.ex1b == 0 && spec.ex2a == 1 && univ.party.in_boat >= 0)
|
||||
|
@@ -430,6 +430,11 @@ bool cParty::give_item(cItem item,bool do_print) {
|
||||
// TODO: Utilize the second parameter in special node processing
|
||||
// if abil > 0, force abil, else ignore
|
||||
bool cParty::forced_give(item_num_t item_num,eItemAbil abil,short dat) {
|
||||
bool force_equip = false;
|
||||
if(item_num >= 10000) {
|
||||
item_num -= 10000;
|
||||
force_equip = true;
|
||||
}
|
||||
if(item_num < 0 || item_num >= univ.scenario.scen_items.size())
|
||||
return true;
|
||||
cItem item = univ.scenario.scen_items[item_num];
|
||||
@@ -442,6 +447,8 @@ bool cParty::forced_give(item_num_t item_num,eItemAbil abil,short dat) {
|
||||
for(int j = 0; j < 24; j++)
|
||||
if(adven[i]->main_status == eMainStatus::ALIVE && adven[i]->items[j].variety == eItemType::NO_ITEM) {
|
||||
adven[i]->items[j] = item;
|
||||
if(force_equip)
|
||||
adven[i]->equip[j] = true;
|
||||
|
||||
if(print_result) {
|
||||
std::ostringstream announce;
|
||||
|
@@ -605,13 +605,13 @@ enum class eSpecType {
|
||||
AFFECT_TRAITS = 88,
|
||||
AFFECT_AP = 89,
|
||||
AFFECT_NAME = 90,
|
||||
UNUSED30 = 91,
|
||||
UNUSED31 = 92,
|
||||
UNUSED32 = 93,
|
||||
UNUSED33 = 94,
|
||||
UNUSED34 = 95,
|
||||
UNUSED35 = 96,
|
||||
UNUSED36 = 97,
|
||||
AFFECT_LEVEL = 91,
|
||||
AFFECT_MORALE = 92,
|
||||
AFFECT_SOUL_CRYSTAL = 93,
|
||||
AFFECT_EQUIPPED = 94,
|
||||
AFFECT_MONST_TARG = 95,
|
||||
AFFECT_MONST_ATT = 96,
|
||||
AFFECT_MONST_STAT = 97,
|
||||
AFFECT_STAT = 98,
|
||||
AFFECT_MAGE_SPELL = 99,
|
||||
AFFECT_PRIEST_SPELL = 100,
|
||||
|
Reference in New Issue
Block a user