Merge all the status effect special nodes

- It's now possible to affect weapon poison, martyr's shield, acid, and life detection from a special node
- Affect nodes now always take resistances into account when harming, but never when helping
This commit is contained in:
2015-01-16 10:33:57 -05:00
parent 39723d1a94
commit d729bcc86b
9 changed files with 362 additions and 326 deletions

View File

@@ -110,7 +110,7 @@ Unused
Unused
Special to Jump To
--------------------
Affect Poison
Affect Status Effect
Unused
Unused
First part of message
@@ -118,168 +118,168 @@ Second part of message
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Amount (usually 0 .. 8)
0 - help, 1 - harm
Which effect (0 .. 13)
Unused
Unused
Unused
Special to Jump To
--------------------
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Slow/Haste
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Invulnerability
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Magic Resistance
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Webs
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Disease
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Sanctuary
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - adds, 1 - removes
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Curse/Bless
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 8)
0 - blesses, 1 - curses
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Dumbfounding
Unused
Unused
First part of message
Second part of message
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Unused
Amount (0 .. 7)
0 - cure, 1 - inflict
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Sleep
Unused
Unused
First part of message
Second part of message
Unused
Unused
Unused
Amount (0 .. 8)
0 - cure, 1 - inflict
Unused Node
Unused
Unused
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Paralysis
Unused
Unused
First part of message
Second part of message
Unused
Unused
Unused
Amount (0 .. 5000)
0 - cure, 1 - inflict
Unused
Unused
Unused
@@ -382,7 +382,7 @@ Unused
Unused
Special to Jump To
--------------------
Affect Stealth
Affect Party Status Effect
Unused
Unused
First part of message
@@ -391,39 +391,7 @@ Unused
Unused
Unused
Amount (0 .. 250)
Unused
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Firewalk
Unused
Unused
First part of message
Second part of message
Unused
Unused
Unused
Amount (0 .. 250)
Unused
Unused
Unused
Unused
Unused
Special to Jump To
--------------------
Affect Flying
Unused
Unused
First part of message
Second part of message
Unused
Unused
Unused
Amount (0 .. 250)
Unused
Which effect (0 .. 3)
Unused
Unused
Unused

View File

@@ -2796,7 +2796,7 @@ void monst_basic_abil(short m_num, std::pair<eMonstAbil,uAbility> abil, short ta
case eStatus::INVULNERABLE:
case eStatus::MAGIC_RESISTANCE:
case eStatus::INVISIBLE:
case eStatus::MARTYRS_SHIELD:
case eStatus::MARTYRS_SHIELD: // TODO: Wait what? This one works for monsters!
if(target < 100)
univ.party[target].apply_status(abil.second.gen.stat, -abil.second.gen.strength);
break;

View File

@@ -1101,6 +1101,7 @@ void forced_place_monster(mon_num_t which,location where) {
}
void magic_adjust(cCreature *which_m,short *how_much) {
if(*how_much <= 0) return;
if(which_m->abil[eMonstAbil::ABSORB_SPELLS].active) {
*how_much = 0;
if(32767 - which_m->health > 3)
@@ -1121,16 +1122,18 @@ void magic_adjust(cCreature *which_m,short *how_much) {
}
void poison_monst(cCreature *which_m,short how_much) {
switch(which_m->poison_res) {
case RESIST_HALF:
how_much /= 2;
break;
case RESIST_ALL:
monst_spell_note(which_m->number,10);
return;
case RESIST_DOUBLE:
how_much *= 2;
break;
if(how_much > 0) {
switch(which_m->poison_res) {
case RESIST_HALF:
how_much /= 2;
break;
case RESIST_ALL:
monst_spell_note(which_m->number,10);
return;
case RESIST_DOUBLE:
how_much *= 2;
break;
}
}
which_m->status[eStatus::POISON] = min(8, which_m->status[eStatus::POISON] + how_much);
if(how_much >= 0)
@@ -1210,6 +1213,12 @@ void dumbfound_monst(cCreature *which_m,short how_much) {
void charm_monst(cCreature *which_m,short penalty,eStatus which_status,short amount) {
short r1;
if(which_status != eStatus::CHARM && which_status != eStatus::FORCECAGE && amount < 0) {
which_m->status[which_status] -= amount;
if(which_status == eStatus::PARALYZED)
which_m->status[which_status] = max(0, which_m->status[which_status]);
return;
}
if((which_status == eStatus::ASLEEP) &&
(which_m->m_type == eRace::UNDEAD || which_m->m_type == eRace::SLIME ||

View File

@@ -2708,165 +2708,153 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
}
}
break;
case eSpecType::AFFECT_POISON:
case eSpecType::AFFECT_STATUS:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
cure_pc(i,spec.ex1a);
if(pc < 0 || pc == i) {
switch(eStatus(spec.ex2a)) {
case eStatus::POISON:
if(spec.ex1b == 0)
cure_pc(i, spec.ex1a);
else poison_pc(i, spec.ex1a);
break;
case eStatus::HASTE_SLOW:
if(spec.ex1b == 0)
slow_pc(i, -spec.ex1a);
else slow_pc(i, spec.ex1a);
break;
case eStatus::INVULNERABLE:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::INVULNERABLE, spec.ex1a);
else univ.party[i].apply_status(eStatus::INVULNERABLE, -spec.ex1a);
break;
case eStatus::MAGIC_RESISTANCE:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::MAGIC_RESISTANCE, spec.ex1a);
else univ.party[i].apply_status(eStatus::MAGIC_RESISTANCE, -spec.ex1a);
break;
case eStatus::WEBS:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::WEBS, -spec.ex1a);
else web_pc(i, spec.ex1a);
break;
case eStatus::DISEASE:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::DISEASE, -spec.ex1a);
else disease_pc(i, spec.ex1a);
break;
case eStatus::INVISIBLE:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::INVISIBLE, spec.ex1a);
else univ.party[i].apply_status(eStatus::INVISIBLE, -spec.ex1a);
break;
case eStatus::BLESS_CURSE:
if(spec.ex1b == 0)
curse_pc(i, -spec.ex1a);
else curse_pc(i, spec.ex1a);
break;
case eStatus::DUMB:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::DUMB, -spec.ex1a);
else dumbfound_pc(i, spec.ex1a);
break;
case eStatus::ASLEEP:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::ASLEEP, -spec.ex1a);
else sleep_pc(i, spec.ex1a, eStatus::ASLEEP, 10);
break;
case eStatus::PARALYZED:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::PARALYZED, -spec.ex1a);
else sleep_pc(i, spec.ex1a, eStatus::PARALYZED, 10);
break;
case eStatus::POISONED_WEAPON:
if(spec.ex1b == 0)
poison_weapon(i, spec.ex1a, true);
else univ.party[i].apply_status(eStatus::POISONED_WEAPON, -spec.ex1a);
break;
case eStatus::MARTYRS_SHIELD:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::MARTYRS_SHIELD, spec.ex1a);
else univ.party[i].apply_status(eStatus::MARTYRS_SHIELD, -spec.ex1a);
break;
case eStatus::ACID:
if(spec.ex1b == 0)
univ.party[i].apply_status(eStatus::ACID, -spec.ex1a);
else acid_pc(i, spec.ex1a);
break;
// Invalid values
case eStatus::MAIN:
case eStatus::CHARM:
case eStatus::FORCECAGE:
break;
}
else poison_pc(i,spec.ex1a);
}
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
poison_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_SPEED:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
slow_pc(i,-spec.ex1a);
}
else slow_pc(i,spec.ex1a);
switch(eStatus(spec.ex2a)) {
case eStatus::POISON:
if(spec.ex1b == 0)
poison_monst(&who, -spec.ex1a);
else poison_monst(&who, spec.ex1a);
break;
case eStatus::HASTE_SLOW:
if(spec.ex1b == 0)
slow_monst(&who, -spec.ex1a);
else slow_monst(&who, spec.ex1a);
break;
case eStatus::WEBS:
if(spec.ex1b == 0)
web_monst(&who, -spec.ex1a);
else web_monst(&who, spec.ex1a);
break;
case eStatus::DISEASE:
if(spec.ex1b == 0)
disease_monst(&who, -spec.ex1a);
else disease_monst(&who, spec.ex1a);
break;
case eStatus::BLESS_CURSE:
if(spec.ex1b == 0)
curse_monst(&who, -spec.ex1a);
else curse_monst(&who, spec.ex1a);
break;
case eStatus::DUMB:
if(spec.ex1b == 0)
dumbfound_monst(&who, -spec.ex1a);
else dumbfound_monst(&who, spec.ex1a);
break;
case eStatus::ASLEEP:
if(spec.ex1b == 0)
charm_monst(&who, 0, eStatus::ASLEEP, -spec.ex1a);
else charm_monst(&who, 0, eStatus::ASLEEP, spec.ex1a);
break;
case eStatus::PARALYZED:
if(spec.ex1b == 0)
charm_monst(&who, 0, eStatus::PARALYZED, -spec.ex1a);
else charm_monst(&who, 0, eStatus::PARALYZED, spec.ex1a);
break;
case eStatus::MARTYRS_SHIELD:
if(spec.ex1b == 0)
who.status[eStatus::MARTYRS_SHIELD] = min(10, who.status[eStatus::MARTYRS_SHIELD] + spec.ex1a);
else who.status[eStatus::MARTYRS_SHIELD] = max(0, who.status[eStatus::MARTYRS_SHIELD] - spec.ex1a);
break;
case eStatus::ACID:
if(spec.ex1b == 0)
acid_monst(&who, -spec.ex1a);
else acid_monst(&who, spec.ex1a);
break;
// Invalid values
case eStatus::MAIN:
case eStatus::FORCECAGE:
case eStatus::POISONED_WEAPON:
case eStatus::INVULNERABLE:
case eStatus::MAGIC_RESISTANCE:
case eStatus::INVISIBLE:
case eStatus::CHARM:
break;
}
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
slow_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_INVULN:
if(pc >= 100) break;
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::INVULNERABLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_MAGIC_RES:
if(pc >= 100) break;
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::MAGIC_RESISTANCE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_WEBS:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::WEBS,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
web_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_DISEASE:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::DISEASE,spec.ex1a * ((spec.ex1b != 0) ? 1: -1));
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
disease_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_SANCTUARY:
if(pc >= 100) break;
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::INVISIBLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_CURSE_BLESS:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::BLESS_CURSE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
curse_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_DUMBFOUND:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
univ.party[i].apply_status(eStatus::DUMB,spec.ex1a * ((spec.ex1b == 0) ? -1: 1));
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
dumbfound_monst(&who,alvl);
}
}
break;
case eSpecType::AFFECT_SLEEP:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
univ.party[i].apply_status(eStatus::ASLEEP,-1 * spec.ex1a);
}
else sleep_pc(i,spec.ex1a,eStatus::ASLEEP,10);
}
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
charm_monst(&who,0,eStatus::ASLEEP,alvl);
}
}
break;
case eSpecType::AFFECT_PARALYSIS:
if(pc < 100) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
univ.party[i].apply_status(eStatus::PARALYZED,-1 * spec.ex1a);
}
else sleep_pc(i,spec.ex1a,eStatus::PARALYZED,10);
}
}
else {
cCreature& who = univ.town.monst[pc - 100];
if(who.active > 0) {
short alvl = spec.ex1a;
if(spec.ex1b == 0)
alvl = -1*alvl;
charm_monst(&who,0,eStatus::PARALYZED,alvl);
}
}
break;
@@ -2928,27 +2916,16 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
}
univ.party.alchemy[spec.ex1a] = true;
break;
case eSpecType::AFFECT_STEALTH:
r1 = (short) univ.party.status[ePartyStatus::STEALTH];
case eSpecType::AFFECT_PARTY_STATUS:
if(spec.ex2a < 0 || spec.ex2a > 3) break;
if(spec.ex2a == 1 && univ.party.in_boat >= 0)
add_string_to_buf(" Can't fly when on a boat. ");
else if(spec.ex2a == 1 && univ.party.in_horse >= 0)////
add_string_to_buf(" Can't fly when on a horse. ");
r1 = univ.party.status[ePartyStatus(spec.ex2a)];
r1 = minmax(0,250,r1 + spec.ex1a);
univ.party.status[ePartyStatus::STEALTH] = r1;
break;
case eSpecType::AFFECT_FIREWALK:
r1 = (short) univ.party.status[ePartyStatus::FIREWALK];
r1 = minmax(0,250,r1 + spec.ex1a);
univ.party.status[ePartyStatus::FIREWALK] = r1;
break;
case eSpecType::AFFECT_FLIGHT:
if(univ.party.in_boat >= 0)
add_string_to_buf(" Can't fly when on a boat. ");
else if(univ.party.in_horse >= 0)////
add_string_to_buf(" Can't fly when on a horse. ");
else {
r1 = (short) univ.party.status[ePartyStatus::FLIGHT];
r1 = minmax(0,250,r1 + spec.ex1a);
univ.party.status[ePartyStatus::FLIGHT] = r1;
}
break;
}
if(check_mess) {
handle_message(which_mode,cur_spec_type,cur_node.m1,cur_node.m2,a,b);

View File

@@ -559,26 +559,24 @@ enum class eSpecType {
AFFECT_XP = 84,
AFFECT_SKILL_PTS = 85,
AFFECT_DEADNESS = 86,
AFFECT_POISON = 87,
AFFECT_SPEED = 88,
AFFECT_INVULN = 89,
AFFECT_MAGIC_RES = 90,
AFFECT_WEBS = 91,
AFFECT_DISEASE = 92,
AFFECT_SANCTUARY = 93,
AFFECT_CURSE_BLESS = 94,
AFFECT_DUMBFOUND = 95,
AFFECT_SLEEP = 96,
AFFECT_PARALYSIS = 97,
AFFECT_STATUS = 87,
UNUSED27 = 88,
UNUSED28 = 89,
UNUSED29 = 90,
UNUSED30 = 91,
UNUSED31 = 92,
UNUSED32 = 93,
UNUSED33 = 94,
UNUSED34 = 95,
UNUSED35 = 96,
UNUSED36 = 97,
AFFECT_STAT = 98,
AFFECT_MAGE_SPELL = 99,
AFFECT_PRIEST_SPELL = 100,
AFFECT_GOLD = 101,
AFFECT_FOOD = 102,
AFFECT_ALCHEMY = 103,
AFFECT_STEALTH = 104,
AFFECT_FIREWALK = 105,
AFFECT_FLIGHT = 106,
AFFECT_PARTY_STATUS = 104,
IF_SDF = 130,
IF_TOWN_NUM = 131,
IF_RANDOM = 132,
@@ -671,7 +669,7 @@ inline eSpecCat getNodeCategory(eSpecType node) {
return eSpecCat::GENERAL;
if(code >= 50 && code <= 63)
return eSpecCat::ONCE;
if(code >= 80 && code <= 106)
if(code >= 80 && code <= 104)
return eSpecCat::AFFECT;
if(code >= 130 && code <= 157)
return eSpecCat::IF_THEN;

View File

@@ -185,6 +185,19 @@ void cSpecial::append(legacy::special_node_type& old){
if(ex1a > 0) ex1a = 10;
ex2a = 0;
break;
// Party statuses (three nodes collapsed into one)
case 104:
type = eSpecType::AFFECT_STATUS;
ex1c = int(ePartyStatus::STEALTH);
break;
case 105:
type = eSpecType::AFFECT_STATUS;
ex1c = int(ePartyStatus::FIREWALK);
break;
case 106:
type = eSpecType::AFFECT_STATUS;
ex1c = int(ePartyStatus::FLIGHT);
break;
// Place fields (twelve individual node types were collapsed into one)
case 200:
type = eSpecType::RECT_PLACE_FIELD;
@@ -238,6 +251,51 @@ void cSpecial::append(legacy::special_node_type& old){
case 2: sd2 = OBJECT_CRATE; break;
}
break;
// Affect status effect (eleven individual node types were collapsed into one)
case 87:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::POISON);
break;
case 88:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::HASTE_SLOW);
break;
case 89:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::INVULNERABLE);
break;
case 90:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::MAGIC_RESISTANCE);
break;
case 91:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::WEBS);
break;
case 92:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::DISEASE);
break;
case 93:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::INVISIBLE);
break;
case 94:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::BLESS_CURSE);
break;
case 95:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::DUMB);
break;
case 96:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::ASLEEP);
break;
case 97:
type = eSpecType::AFFECT_STATUS;
ex1c = int(eStatus::PARALYZED);
break;
// These are ones that were added in the Windows version but only recently added to the Mac version.
case 28:
type = eSpecType::DISPLAY_PICTURE;
@@ -312,6 +370,8 @@ std::istream& operator >> (std::istream& in, eSpecType& e) {
// L - Choose button to select a town lighting type
// & - Choose button to select shop type
// % - Choose button to select shop cost adjustment
// e - Choose button to select a status effect
// E - Choose button to select a party status effect
static const char*const button_dict[7][11] = {
{ // general nodes
" mmmMMmmmm mmm mmmmmm Mmm $ mmmmmm", // msg1
@@ -338,17 +398,17 @@ static const char*const button_dict[7][11] = {
"s ssssss ", // ex2b
" ", // ex2c
}, { // affect pc nodes
"mmmmmmmmmmmmmmmmmmmmmmmmmmm", // msg1
" ", // msg2
" ", // msg3
" ", // pic
" ", // pictype
" AP a ", // ex1a
" ", // ex1b
" ", // ex1c
" K ", // ex2a
" D ", // ex2b
" x ", // ex2c
"mmmmmmmm mmmmmmm", // msg1
" ", // msg2
" ", // msg3
" ", // pic
" ", // pictype
" AP a ", // ex1a
" E", // ex1b
" e ", // ex1c
" K ", // ex2a
" D ", // ex2b
" x ", // ex2c
}, { // if-then nodes
" $ $", // msg1
" ", // msg2

View File

@@ -23,16 +23,16 @@
const size_t cPictChoice::per_page = 36;
cPictChoice::cPictChoice(std::vector<pic_num_t>& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {}
cPictChoice::cPictChoice(const std::vector<pic_num_t>& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {}
cPictChoice::cPictChoice(std::vector<std::pair<pic_num_t,ePicType>>& pics,cDialog* parent) : dlg("choose-pict",parent) {
cPictChoice::cPictChoice(const std::vector<std::pair<pic_num_t,ePicType>>& pics,cDialog* parent) : dlg("choose-pict",parent) {
picts = pics;
attachHandlers();
}
cPictChoice::cPictChoice(
std::vector<pic_num_t>::iterator begin,
std::vector<pic_num_t>::iterator end,
std::vector<pic_num_t>::const_iterator begin,
std::vector<pic_num_t>::const_iterator end,
ePicType t,
cDialog* parent
) : dlg("choose-pict",parent) {

View File

@@ -216,17 +216,17 @@ public:
/// @param pics A list of all icons in the dialog.
/// @param t The type of icons to show; all icons are assumed to be of the same type.
/// @param parent Optionally, a parent dialog.
cPictChoice(std::vector<pic_num_t>& pics, ePicType t, cDialog* parent = NULL);
cPictChoice(const std::vector<pic_num_t>& pics, ePicType t, cDialog* parent = NULL);
/// Initializes a dialog from a list of icons.
/// @param pics A list of all icons in the dialog as {num,type} pairs.
/// @param parent Optionally, a parent dialog.
cPictChoice(std::vector<std::pair<pic_num_t,ePicType>>& pics, cDialog* parent = NULL);
cPictChoice(const std::vector<std::pair<pic_num_t,ePicType>>& pics, cDialog* parent = NULL);
/// Initializes a dialog from an iterator pair.
/// @param begin An iterator to the first icon in the dialog.
/// @param end An iterator to one past the last icon in the dialog.
/// @param t The type of icons to show; all icons are assumed to be of the same type.
/// @param parent Optionally, a parent dialog.
cPictChoice(std::vector<pic_num_t>::iterator begin, std::vector<pic_num_t>::iterator end, ePicType t, cDialog* parent = NULL);
cPictChoice(std::vector<pic_num_t>::const_iterator begin, std::vector<pic_num_t>::const_iterator end, ePicType t, cDialog* parent = NULL);
/// Initializes a dialog from an index pair.
/// @param first The number of the first icon in the dialog.
/// @param last The number of the last icon in the dialog.

View File

@@ -576,7 +576,7 @@ static short choose_field_type(short cur, cDialog* parent, bool includeSpec) {
static pic_num_t choose_damage_type(short cur, cDialog* parent) {
static const char*const damageNames[] = {"Weapon", "Fire", "Poison", "Magic", "Unblockable", "Cold", "Undead", "Demon"};
static std::vector<pic_num_t> pics = {3,0,2,1,1,4,3,3};
static const std::vector<pic_num_t> pics = {3,0,2,1,1,4,3,3};
short prev = cur;
if(cur < 0 || cur >= pics.size()) cur = 0;
cPictChoice pic_dlg(pics, PIC_BOOM, parent);
@@ -592,7 +592,7 @@ static pic_num_t choose_damage_type(short cur, cDialog* parent) {
static pic_num_t choose_boom_type(short cur, cDialog* parent) {
static const char*const boomNames[] = {"Fire", "Magic/Cold/Electricity", "Teleport", "Magic/Electricity"};
static std::vector<pic_num_t> pics = {12,28,20,36};
static const std::vector<pic_num_t> pics = {12,28,20,36};
short prev = cur;
if(cur < 0 || cur >= pics.size()) cur = 0;
cPictChoice pic_dlg(pics, PIC_BOOM, parent);
@@ -606,6 +606,28 @@ static pic_num_t choose_boom_type(short cur, cDialog* parent) {
return made_choice ? item_hit : prev;
}
static pic_num_t choose_status_effect(short cur, bool party, cDialog* parent) {
static const char*const status[] = {
"Poisoned Weapon", "Bless/Curse", "Poison", "Haste/Slow", "Invulnerable",
"Magic Resist/Amplify", "Webs", "Disease", "Sanctuary", "Dumbfounding/Enlightening",
"Martyr's Shield", "Sleep/Hyperactivity", "Paralysis", "Acid"
};
static const char*const pstatus[] = {"Stealth", "Flight", "Detect Life", "Firewalk"};
static const std::vector<pic_num_t> status_pics = {4,0,2,6,5,9,10,11,13,14,15,16,17,18};
static const std::vector<pic_num_t> pstatus_pics = {25,23,24,26};
short prev = cur;
if(cur < 0 || cur >= (party ? pstatus_pics : status_pics).size()) cur = 0;
cPictChoice pic_dlg(party ? pstatus_pics : status_pics, PIC_STATUS, parent);
pic_dlg->getControl("prompt").setText("Select a status effect:");
pic_dlg->getControl("help").setText((party ? pstatus : status)[cur]);
pic_dlg.attachSelectHandler([party](cPictChoice& me, int n) {
me->getControl("help").setText((party ? pstatus : status)[n]);
});
bool made_choice = pic_dlg.show(cur);
size_t item_hit = pic_dlg.getSelected();
return made_choice ? item_hit : prev;
}
static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t& edit_stack) {
std::string field = item_hit.substr(0, item_hit.find_first_of('-'));
char btn;
@@ -691,6 +713,8 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
case 'f': case 'F': choose_string = false; store = choose_field_type(val, &me, btn == 'F'); break;
case 'D': choose_string = false; store = choose_damage_type(val, &me); break;
case '!': choose_string = false; store = choose_boom_type(val, &me); break;
case 'e': choose_string = false; store = choose_status_effect(val, false, &me); break;
case 'E': choose_string = false; store = choose_status_effect(val, true, &me); break;
case 'i': strt = STRT_ITEM; title = "Which item?"; break;
case 'I': strt = STRT_SPEC_ITEM; title = "Which special item?"; break;
case 't': strt = STRT_TER; title = "Which terrain?"; break;