diff --git a/rsrc/strings/specials-text-affect.txt b/rsrc/strings/specials-text-affect.txt index 41581776..1d118df3 100644 --- a/rsrc/strings/specials-text-affect.txt +++ b/rsrc/strings/specials-text-affect.txt @@ -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 diff --git a/src/boe.combat.cpp b/src/boe.combat.cpp index 4569829a..08a50b77 100644 --- a/src/boe.combat.cpp +++ b/src/boe.combat.cpp @@ -2796,7 +2796,7 @@ void monst_basic_abil(short m_num, std::pair 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; diff --git a/src/boe.monster.cpp b/src/boe.monster.cpp index 1d28124a..5169146d 100644 --- a/src/boe.monster.cpp +++ b/src/boe.monster.cpp @@ -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 || diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index 9b50776d..a6a1b042 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -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); diff --git a/src/classes/simpletypes.h b/src/classes/simpletypes.h index e807863c..613d1168 100644 --- a/src/classes/simpletypes.h +++ b/src/classes/simpletypes.h @@ -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; diff --git a/src/classes/special.cpp b/src/classes/special.cpp index b6ce018f..3fb7baba 100644 --- a/src/classes/special.cpp +++ b/src/classes/special.cpp @@ -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 diff --git a/src/dialogxml/dlogutil.cpp b/src/dialogxml/dlogutil.cpp index ddf1593a..46d63564 100644 --- a/src/dialogxml/dlogutil.cpp +++ b/src/dialogxml/dlogutil.cpp @@ -23,16 +23,16 @@ const size_t cPictChoice::per_page = 36; -cPictChoice::cPictChoice(std::vector& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {} +cPictChoice::cPictChoice(const std::vector& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {} -cPictChoice::cPictChoice(std::vector>& pics,cDialog* parent) : dlg("choose-pict",parent) { +cPictChoice::cPictChoice(const std::vector>& pics,cDialog* parent) : dlg("choose-pict",parent) { picts = pics; attachHandlers(); } cPictChoice::cPictChoice( - std::vector::iterator begin, - std::vector::iterator end, + std::vector::const_iterator begin, + std::vector::const_iterator end, ePicType t, cDialog* parent ) : dlg("choose-pict",parent) { diff --git a/src/dialogxml/dlogutil.hpp b/src/dialogxml/dlogutil.hpp index 84ffd8d3..4457616e 100644 --- a/src/dialogxml/dlogutil.hpp +++ b/src/dialogxml/dlogutil.hpp @@ -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& pics, ePicType t, cDialog* parent = NULL); + cPictChoice(const std::vector& 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>& pics, cDialog* parent = NULL); + cPictChoice(const std::vector>& 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::iterator begin, std::vector::iterator end, ePicType t, cDialog* parent = NULL); + cPictChoice(std::vector::const_iterator begin, std::vector::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. diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index a42aa3f6..97c5a129 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -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 pics = {3,0,2,1,1,4,3,3}; + static const std::vector 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 pics = {12,28,20,36}; + static const std::vector 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 status_pics = {4,0,2,6,5,9,10,11,13,14,15,16,17,18}; + static const std::vector 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;