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

@@ -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

View File

@@ -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<std::string, 6> 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;

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
// 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) {

View File

@@ -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