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
This commit is contained in:
2015-01-20 13:48:51 -05:00
parent 4c271140c6
commit 42639882e3
6 changed files with 44 additions and 35 deletions

View File

@@ -212,13 +212,13 @@ Stuff Done Flag Part B
First part of message First part of message
Second part of message Second part of message
Unused Unused
Unused Picture number
Unused Picture type
Type of trap Type of trap
Trap severity (0 .. 3) Trap severity (0 .. 3)
Unused Unused
Penalty (0 .. 100, higher is harder) Penalty (0 .. 100, higher is harder)
Unused (Custom only) Special node for effect
Unused Unused
Special after trap finished Special after trap finished
-------------------- --------------------

View File

@@ -10,3 +10,4 @@ Flames
Dumbfound Dumbfound
Disease Disease
Foul Spray (disease all) Foul Spray (disease all)
Custom Effect

View File

@@ -27,6 +27,7 @@
#define SDF_SPEC_LOC_Y 301][1 #define SDF_SPEC_LOC_Y 301][1
#define SDF_SPEC_TER 301][2 #define SDF_SPEC_TER 301][2
#define SDF_SPEC_STRBUF 301][3 #define SDF_SPEC_STRBUF 301][3
#define SDF_SPEC_TRAPLVL 301][4
#define SDF_SKIP_STARTUP 305][4 // preferably deprecated #define SDF_SKIP_STARTUP 305][4 // preferably deprecated
#define SDF_LESS_SOUND 305][5 #define SDF_LESS_SOUND 305][5
#define SDF_NO_TARGET_LINE 305][6 #define SDF_NO_TARGET_LINE 305][6
@@ -142,6 +143,7 @@ enum eTrapType {
TRAP_DUMBFOUND = 10, //dumbfound all TRAP_DUMBFOUND = 10, //dumbfound all
TRAP_DISEASE = 11, TRAP_DISEASE = 11,
TRAP_DISEASE_ALL = 12, TRAP_DISEASE_ALL = 12,
TRAP_CUSTOM = 13,
}; };
// Startup button rects // Startup button rects

View File

@@ -2036,6 +2036,7 @@ void run_special(eSpecCtx which_mode,short which_type,short start_spec,location
else erase_specials(); else erase_specials();
special_in_progress = false; 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()) { if(next_spec == -1 && !special_queue.empty()) {
pending_special_type pending = special_queue.front(); pending_special_type pending = special_queue.front();
special_queue.pop(); 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? // TODO: What was next_spec_type for? Is it still needed?
void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, 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; bool check_mess = true,set_sd = true;
std::array<std::string, 6> strs; std::array<std::string, 6> strs;
short i,j; 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)) { if((spec.m1 >= 0) || (spec.m2 >= 0)) {
get_strs(strs[0],strs[1], cur_spec_type, spec.m1, spec.m2); get_strs(strs[0],strs[1], cur_spec_type, spec.m1, spec.m2);
buttons[0] = 3; buttons[1] = 2; buttons[0] = 3; buttons[1] = 2;
// TODO: Why not allow a choice of dialog picture? i = custom_choice_dialog(strs,spec.pic,ePicType(spec.pictype),buttons);
i = custom_choice_dialog(strs,27,PIC_DLOG,buttons);
// TODO: Make custom_choice_dialog return string? // TODO: Make custom_choice_dialog return string?
} }
else i = cChoiceDlog("basic-trap",{"yes","no"}).show() == "no"; else i = cChoiceDlog("basic-trap",{"yes","no"}).show() == "no";
if(i == 1) {set_sd = false; *next_spec = -1; *a = 1;} if(i == 1) {
else { set_sd = false;
if(is_combat()) *next_spec = -1;
j = run_trap(current_pc,(eTrapType)spec.ex1a,spec.ex1b,spec.ex2a); *a = 1;
else j = run_trap(7,(eTrapType)spec.ex1a,spec.ex1b,spec.ex2a); } else {
if(j == 0) { if(!is_combat()) {
*a = 1; set_sd = false; 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; break;

View File

@@ -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 //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 // 7 - level drain 8 - alert 9 - big flames 10 - dumbfound 11 - disease 1
// 12 - disease all // 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, 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}; 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; num_hits += trap_level;
if(trap_type == TRAP_RANDOM) 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) if(trap_type == TRAP_FALSE_ALARM)
return true; 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. "); add_string_to_buf(" Poison gas pours out. ");
r1 = 2 + univ.town.difficulty / 14; r1 = 2 + univ.town.difficulty / 14;
r1 = r1 + trap_level * 2; r1 = r1 + trap_level * 2;
for(i = 0; i < 6; i++) poison_party(r1);
poison_pc(i,r1);
break; break;
case TRAP_EXPLOSION: 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); disease_pc(i,r1);
break; break;
case TRAP_CUSTOM:
univ.party.force_ptr(5, 301, 4);
PSD[SDF_SPEC_TRAPLVL] = trap_level;
break;
default: default:
add_string_to_buf("ERROR: Invalid trap type."); // should never be reached add_string_to_buf("ERROR: Invalid trap type."); // should never be reached
} }
put_pc_screen(); put_pc_screen();
put_item_screen(stat_window,0); put_item_screen(stat_window,0);
return true; return false;
} }
location get_spec_loc(short which) { location get_spec_loc(short which) {

View File

@@ -118,6 +118,11 @@ void cSpecial::append(legacy::special_node_type& old){
type = eSpecType::IF_TRAIT; type = eSpecType::IF_TRAIT;
ex1a = old.type - 147; ex1a = old.type - 147;
break; 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 case 153: // if enough mage lore
type = eSpecType::IF_STATISTIC; type = eSpecType::IF_STATISTIC;
if(ex2a >= 0) { // Windows version added "if statistic" much earlier, but it still needs a little conversion. 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 "mm mddddddmmm", // msg1
" ", // msg2 " ", // msg2
" III ", // msg3 " III ", // msg3
" pppppp ", // pic " pppppp p", // pic
" ?????? ", // pictype " ?????? ?", // pictype
"iI bbbiii X", // ex1a "iI bbbiii X", // ex1a
" sss ", // ex1b " sss ", // ex1b
" ", // ex1c " ", // ex1c
" bbb ", // ex2a " bbb ", // ex2a
"s ssssss ", // ex2b "s ssssss S", // ex2b
" ", // ex2c " ", // ex2c
}, { // affect pc nodes }, { // affect pc nodes
"mmmmmmmmmmm mmmmmmmm", // msg1 "mmmmmmmmmmm mmmmmmmm", // msg1