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:
@@ -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
|
||||||
--------------------
|
--------------------
|
||||||
|
@@ -9,4 +9,5 @@ Alarm (town hostile)
|
|||||||
Flames
|
Flames
|
||||||
Dumbfound
|
Dumbfound
|
||||||
Disease
|
Disease
|
||||||
Foul Spray (disease all)
|
Foul Spray (disease all)
|
||||||
|
Custom Effect
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user