From 42639882e3903dd5b5fb667cc1cf8a6a7d2f5205 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Tue, 20 Jan 2015 13:48:51 -0500 Subject: [PATCH] Add option to call a scenario special node to apply the effect of a trap Also: - The possible traps resulting from "random trap" is expanded to include the knife trap - A custom picture can be specified for the trap dialog - A given custom trap special node can be reused for the same trap with different levels - the pointer -5 holds the trap level passed to the ONCE_TRAP node --- rsrc/strings/specials-text-once.txt | 6 +++--- rsrc/strings/trap-types.txt | 3 ++- src/boe.consts.h | 2 ++ src/boe.specials.cpp | 31 +++++++++++++++++++---------- src/boe.townspec.cpp | 26 ++++++++---------------- src/classes/special.cpp | 11 +++++++--- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/rsrc/strings/specials-text-once.txt b/rsrc/strings/specials-text-once.txt index 08f5a137..5a55536e 100644 --- a/rsrc/strings/specials-text-once.txt +++ b/rsrc/strings/specials-text-once.txt @@ -212,13 +212,13 @@ Stuff Done Flag Part B First part of message Second part of message Unused -Unused -Unused +Picture number +Picture type Type of trap Trap severity (0 .. 3) Unused Penalty (0 .. 100, higher is harder) -Unused +(Custom only) Special node for effect Unused Special after trap finished -------------------- diff --git a/rsrc/strings/trap-types.txt b/rsrc/strings/trap-types.txt index 84941c8e..1350496a 100644 --- a/rsrc/strings/trap-types.txt +++ b/rsrc/strings/trap-types.txt @@ -9,4 +9,5 @@ Alarm (town hostile) Flames Dumbfound Disease -Foul Spray (disease all) \ No newline at end of file +Foul Spray (disease all) +Custom Effect \ No newline at end of file diff --git a/src/boe.consts.h b/src/boe.consts.h index df11cbca..e8877511 100644 --- a/src/boe.consts.h +++ b/src/boe.consts.h @@ -27,6 +27,7 @@ #define SDF_SPEC_LOC_Y 301][1 #define SDF_SPEC_TER 301][2 #define SDF_SPEC_STRBUF 301][3 +#define SDF_SPEC_TRAPLVL 301][4 #define SDF_SKIP_STARTUP 305][4 // preferably deprecated #define SDF_LESS_SOUND 305][5 #define SDF_NO_TARGET_LINE 305][6 @@ -142,6 +143,7 @@ enum eTrapType { TRAP_DUMBFOUND = 10, //dumbfound all TRAP_DISEASE = 11, TRAP_DISEASE_ALL = 12, + TRAP_CUSTOM = 13, }; // Startup button rects diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index 91f40ced..919877bf 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -2036,6 +2036,7 @@ void run_special(eSpecCtx which_mode,short which_type,short start_spec,location else erase_specials(); special_in_progress = false; + // TODO: Should find a way to do this that doesn't risk stack overflow if(next_spec == -1 && !special_queue.empty()) { pending_special_type pending = special_queue.front(); special_queue.pop(); @@ -2410,7 +2411,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, // TODO: What was next_spec_type for? Is it still needed? void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, - short *next_spec,short* /*next_spec_type*/,short *a,short *b,short *redraw) { + short* next_spec,short* next_spec_type,short* a,short* b,short* redraw) { bool check_mess = true,set_sd = true; std::array strs; short i,j; @@ -2540,18 +2541,28 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, if((spec.m1 >= 0) || (spec.m2 >= 0)) { get_strs(strs[0],strs[1], cur_spec_type, spec.m1, spec.m2); buttons[0] = 3; buttons[1] = 2; - // TODO: Why not allow a choice of dialog picture? - i = custom_choice_dialog(strs,27,PIC_DLOG,buttons); + i = custom_choice_dialog(strs,spec.pic,ePicType(spec.pictype),buttons); // TODO: Make custom_choice_dialog return string? } else i = cChoiceDlog("basic-trap",{"yes","no"}).show() == "no"; - if(i == 1) {set_sd = false; *next_spec = -1; *a = 1;} - else { - if(is_combat()) - j = run_trap(current_pc,(eTrapType)spec.ex1a,spec.ex1b,spec.ex2a); - else j = run_trap(7,(eTrapType)spec.ex1a,spec.ex1b,spec.ex2a); - if(j == 0) { - *a = 1; set_sd = false; + if(i == 1) { + set_sd = false; + *next_spec = -1; + *a = 1; + } else { + if(!is_combat()) { + j = char_select_pc(0,"Trap! Who will disarm?"); + if(j == 6){ + *a = 1; + set_sd = false; + } + } else j = current_pc; + bool disarmed = run_trap(j,eTrapType(spec.ex1a),spec.ex1b,spec.ex2a); + if(!disarmed && spec.ex1a == TRAP_CUSTOM) { + if(spec.jumpto >= 0) + queue_special(which_mode, cur_spec_type, spec.jumpto, loc(PSD[SDF_SPEC_LOC_X], PSD[SDF_SPEC_LOC_Y])); + *next_spec = spec.ex2b; + *next_spec_type = 0; } } break; diff --git a/src/boe.townspec.cpp b/src/boe.townspec.cpp index 69a0d519..526b698a 100644 --- a/src/boe.townspec.cpp +++ b/src/boe.townspec.cpp @@ -34,7 +34,6 @@ void activate_monster_enc(short enc_num,std::string list,short str,short strsnd, } } -//short pc_num; // 6 - BOOM! 7 - pick here //short trap_type; // 0 - random 1 - blade 2 - dart 3 - gas 4 - boom 5 - paralyze 6 - no // 7 - level drain 8 - alert 9 - big flames 10 - dumbfound 11 - disease 1 // 12 - disease all @@ -43,23 +42,10 @@ bool run_trap(short pc_num,eTrapType trap_type,short trap_level,short diff) { short trap_odds[30] = {5,30,35,42,48, 55,63,69,75,77, 78,80,82,84,86, 88,90,92,94,96,98,99,99,99,99,99,99,99,99,99}; - if(pc_num > 7) { // Debug - beep(); - ASB("TRAP ERROR! REPORT!"); - return true; - } - - if(pc_num == 7) { - pc_num = char_select_pc(0,"Trap! Who will disarm?"); - if(pc_num == 6) - return false; - } - - num_hits += trap_level; if(trap_type == TRAP_RANDOM) - trap_type = (eTrapType) get_ran(1,1,4); + trap_type = (eTrapType) get_ran(1,0,4); if(trap_type == TRAP_FALSE_ALARM) return true; @@ -102,8 +88,7 @@ bool run_trap(short pc_num,eTrapType trap_type,short trap_level,short diff) { add_string_to_buf(" Poison gas pours out. "); r1 = 2 + univ.town.difficulty / 14; r1 = r1 + trap_level * 2; - for(i = 0; i < 6; i++) - poison_pc(i,r1); + poison_party(r1); break; case TRAP_EXPLOSION: @@ -158,12 +143,17 @@ bool run_trap(short pc_num,eTrapType trap_type,short trap_level,short diff) { disease_pc(i,r1); break; + case TRAP_CUSTOM: + univ.party.force_ptr(5, 301, 4); + PSD[SDF_SPEC_TRAPLVL] = trap_level; + break; + default: add_string_to_buf("ERROR: Invalid trap type."); // should never be reached } put_pc_screen(); put_item_screen(stat_window,0); - return true; + return false; } location get_spec_loc(short which) { diff --git a/src/classes/special.cpp b/src/classes/special.cpp index e2fb7fed..23e411ac 100644 --- a/src/classes/special.cpp +++ b/src/classes/special.cpp @@ -118,6 +118,11 @@ void cSpecial::append(legacy::special_node_type& old){ type = eSpecType::IF_TRAIT; ex1a = old.type - 147; break; + case 63: // Trap used to force a specific picture + type = eSpecType::ONCE_TRAP; + pic = 27; + pictype = PIC_DLOG; + break; case 153: // if enough mage lore type = eSpecType::IF_STATISTIC; if(ex2a >= 0) { // Windows version added "if statistic" much earlier, but it still needs a little conversion. @@ -394,13 +399,13 @@ static const char*const button_dict[7][11] = { "mm mddddddmmm", // msg1 " ", // msg2 " III ", // msg3 - " pppppp ", // pic - " ?????? ", // pictype + " pppppp p", // pic + " ?????? ?", // pictype "iI bbbiii X", // ex1a " sss ", // ex1b " ", // ex1c " bbb ", // ex2a - "s ssssss ", // ex2b + "s ssssss S", // ex2b " ", // ex2c }, { // affect pc nodes "mmmmmmmmmmm mmmmmmmm", // msg1