diff options
-rw-r--r-- | crawl-ref/source/branch.cc | 25 | ||||
-rw-r--r-- | crawl-ref/source/branch.h | 10 | ||||
-rw-r--r-- | crawl-ref/source/cloud.cc | 161 | ||||
-rw-r--r-- | crawl-ref/source/cloud.h | 27 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 98 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 27 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/traps.cc | 194 | ||||
-rw-r--r-- | crawl-ref/source/traps.h | 19 |
9 files changed, 483 insertions, 81 deletions
diff --git a/crawl-ref/source/branch.cc b/crawl-ref/source/branch.cc index d8e36f1a6c..26411173ef 100644 --- a/crawl-ref/source/branch.cc +++ b/crawl-ref/source/branch.cc @@ -4,10 +4,12 @@ #include "AppHdr.h" #include "branch.h" +#include "cloud.h" #include "externs.h" #include "mon-pick.h" #include "player.h" #include "spells3.h" +#include "traps.h" Branch& your_branch() { @@ -115,6 +117,7 @@ Branch branches[] = { NULL, true, true, LIGHTGREY, BROWN, mons_standard_rare, mons_standard_level, + NULL, NULL, NULL, NULL, 8, 'D', false, false }, { BRANCH_ECUMENICAL_TEMPLE, BRANCH_MAIN_DUNGEON, 1, 5, 0, 0, @@ -123,6 +126,7 @@ Branch branches[] = { NULL, false, false, LIGHTGREY, LIGHTGREY, mons_standard_rare, mons_standard_level, + traps_zero_number, NULL, NULL, NULL, // No traps in temple 0, 'T', false, false }, { BRANCH_ORCISH_MINES, BRANCH_MAIN_DUNGEON, 4, 6, 0, 0, @@ -131,6 +135,7 @@ Branch branches[] = { NULL, true, false, BROWN, BROWN, mons_mineorc_rare, mons_mineorc_level, + NULL, NULL, NULL, NULL, 20, 'O', false, false }, { BRANCH_ELVEN_HALLS, BRANCH_ORCISH_MINES, 7, 4, 0, 0, @@ -139,6 +144,7 @@ Branch branches[] = { NULL, true, true, DARKGREY, LIGHTGREY, mons_hallelf_rare, mons_hallelf_level, + NULL, NULL, NULL, NULL, 8, 'E', false, true }, { BRANCH_LAIR, BRANCH_MAIN_DUNGEON, 10, 8, 0, 0, @@ -147,6 +153,7 @@ Branch branches[] = { NULL, true, false, GREEN, BROWN, mons_lair_rare, mons_lair_level, + NULL, NULL, NULL, NULL, 5, 'L', false, false }, { BRANCH_SWAMP, BRANCH_LAIR, 5, 3, 0, 0, @@ -155,6 +162,7 @@ Branch branches[] = { NULL, true, true, BROWN, BROWN, mons_swamp_rare, mons_swamp_level, + NULL, NULL, NULL, NULL, 0, 'S', false, true }, { BRANCH_SHOALS, BRANCH_LAIR, 5, 4, 0, 0, @@ -163,6 +171,7 @@ Branch branches[] = { NULL, true, true, BROWN, BROWN, mons_shoals_rare, mons_shoals_level, + NULL, NULL, NULL, NULL, 0, 'A', false, true }, { BRANCH_SLIME_PITS, BRANCH_LAIR, 6, 4, 0, 0, @@ -171,6 +180,7 @@ Branch branches[] = { NULL, false, false, GREEN, LIGHTGREEN, mons_pitslime_rare, mons_pitslime_level, + NULL, NULL, NULL, NULL, 5, 'M', false, true }, { BRANCH_SNAKE_PIT, BRANCH_LAIR, 5, 7, 0, 0, @@ -179,6 +189,7 @@ Branch branches[] = { NULL, true, true, LIGHTGREEN, YELLOW, mons_pitsnake_rare, mons_pitsnake_level, + NULL, NULL, NULL, NULL, 10, 'P', false, true }, { BRANCH_HIVE, BRANCH_MAIN_DUNGEON, 4, 15, 0, 0, @@ -187,6 +198,7 @@ Branch branches[] = { "You hear a buzzing sound coming from all directions.", false, false, YELLOW, BROWN, mons_hive_rare, mons_hive_level, + NULL, NULL, NULL, NULL, 0, 'H', false, true }, { BRANCH_VAULTS, BRANCH_MAIN_DUNGEON, 8, 17, 0, 0, @@ -195,6 +207,7 @@ Branch branches[] = { NULL, true, true, LIGHTGREY, BROWN, mons_standard_rare, mons_standard_level, + NULL, NULL, NULL, NULL, 5, 'V', false, true }, @@ -204,6 +217,7 @@ Branch branches[] = { NULL, false, true, LIGHTGREY, LIGHTGREY, mons_hallblade_rare, mons_hallblade_level, + NULL, NULL, NULL, NULL, 0, 'B', false, false }, { BRANCH_CRYPT, BRANCH_VAULTS, 5, 3, 0, 0, @@ -212,6 +226,7 @@ Branch branches[] = { NULL, false, true, LIGHTGREY, LIGHTGREY, mons_crypt_rare, mons_crypt_level, + NULL, NULL, NULL, NULL, 5, 'C', false, false }, { BRANCH_TOMB, BRANCH_CRYPT, 3, 5, 0, 0, @@ -220,6 +235,7 @@ Branch branches[] = { NULL, false, true, YELLOW, LIGHTGREY, mons_tomb_rare, mons_tomb_level, + NULL, NULL, NULL, NULL, 0, 'G', false, true }, { BRANCH_VESTIBULE_OF_HELL, BRANCH_MAIN_DUNGEON, 1, -1, 0, 0, @@ -228,6 +244,7 @@ Branch branches[] = { NULL, false, true, LIGHTGREY, LIGHTGREY, mons_standard_rare, mons_standard_level, + NULL, NULL, NULL, NULL, 0, 'U', false, false }, { BRANCH_DIS, BRANCH_VESTIBULE_OF_HELL, 7, -1, 0, 0, @@ -236,6 +253,7 @@ Branch branches[] = { NULL, false, false, CYAN, CYAN, mons_dis_rare, mons_dis_level, + NULL, NULL, NULL, NULL, 0, 'I', true, true }, { BRANCH_GEHENNA, BRANCH_VESTIBULE_OF_HELL, 7, -1, 0, 0, @@ -244,6 +262,7 @@ Branch branches[] = { NULL, false, false, DARKGREY, RED, mons_gehenna_rare, mons_gehenna_level, + NULL, NULL, NULL, NULL, 0, 'N', true, true }, { BRANCH_COCYTUS, BRANCH_VESTIBULE_OF_HELL, 7, -1, 0, 0, @@ -252,6 +271,7 @@ Branch branches[] = { NULL, false, false, LIGHTBLUE, LIGHTCYAN, mons_cocytus_rare, mons_cocytus_level, + NULL, NULL, NULL, NULL, 0, 'X', true, true }, { BRANCH_TARTARUS, BRANCH_VESTIBULE_OF_HELL, 7, -1, 0, 0, @@ -260,6 +280,7 @@ Branch branches[] = { NULL, false, false, DARKGREY, DARKGREY, mons_tartarus_rare, mons_tartarus_level, + NULL, NULL, NULL, NULL, 0, 'Y', true, true }, { BRANCH_INFERNO, BRANCH_MAIN_DUNGEON, -1, -1, 0, 0, @@ -268,6 +289,7 @@ Branch branches[] = { NULL, false, false, BLACK, BLACK, NULL, NULL, + NULL, NULL, NULL, NULL, 0, 'R', false, false }, { BRANCH_THE_PIT, BRANCH_MAIN_DUNGEON, -1, -1, 0, 0, @@ -276,6 +298,7 @@ Branch branches[] = { NULL, false, false, BLACK, BLACK, NULL, NULL, + NULL, NULL, NULL, NULL, 0, '0', false, false }, { BRANCH_HALL_OF_ZOT, BRANCH_MAIN_DUNGEON, 5, 27, BFLAG_HAS_ORB, 0, @@ -284,6 +307,7 @@ Branch branches[] = { NULL, false, true, BLACK, BLACK, mons_hallzot_rare, mons_hallzot_level, + NULL, NULL, NULL, NULL, 1, 'Z', false, true }, { BRANCH_CAVERNS, BRANCH_MAIN_DUNGEON, -1, -1, 0, 0, @@ -292,5 +316,6 @@ Branch branches[] = { NULL, false, false, BLACK, BLACK, NULL, NULL, + NULL, NULL, NULL, NULL, 0, 0, false, false } }; diff --git a/crawl-ref/source/branch.h b/crawl-ref/source/branch.h index 404c40d6b9..0598f31247 100644 --- a/crawl-ref/source/branch.h +++ b/crawl-ref/source/branch.h @@ -12,6 +12,8 @@ #include "enum.h" +struct fog_machine_data; + enum branch_flag_type { BFLAG_NONE = 0, @@ -41,8 +43,12 @@ struct Branch bool has_uniques; char floor_colour; // Zot needs special handling char rock_colour; - int (*mons_rarity_function)(int); - int (*mons_level_function)(int); + int (*mons_rarity_function)(int); + int (*mons_level_function)(int); + int (*num_traps_function)(int); + trap_type (*rand_trap_function)(int); + int (*num_fogs_function)(int); + void (*rand_fog_function)(int,fog_machine_data&); int altar_chance; // in percent int travel_shortcut; // which key to press for travel bool any_upstair_exits; // any upstair exits the branch (Hell branches) diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc index ae7b614045..3d471f41ee 100644 --- a/crawl-ref/source/cloud.cc +++ b/crawl-ref/source/cloud.cc @@ -15,9 +15,11 @@ #include "AppHdr.h" #include "externs.h" +#include "branch.h" #include "cloud.h" #include "mapmark.h" #include "misc.h" +#include "place.h" #include "stuff.h" #include "terrain.h" @@ -310,6 +312,12 @@ cloud_type random_smoke_type() void place_fog_machine(fog_machine_type fm_type, cloud_type cl_type, int x, int y, int size, int power) { + ASSERT(fm_type >= FM_GEYSER && fm_type < NUM_FOG_MACHINE_TYPES); + ASSERT(cl_type > CLOUD_NONE && (cl_type < CLOUD_RANDOM + || cl_type == CLOUD_DEBUGGING)); + ASSERT(size >= 1); + ASSERT(power >= 1); + const char* fog_types[] = { "geyser", "spread", @@ -342,6 +350,159 @@ void place_fog_machine(fog_machine_type fm_type, cloud_type cl_type, } } +void place_fog_machine(fog_machine_data data, int x, int y) +{ + place_fog_machine(data.fm_type, data.cl_type, x, y, data.size, + data.power); +} + +bool valid_fog_machine_data(fog_machine_data data) +{ + if (data.fm_type < FM_GEYSER || data.fm_type >= NUM_FOG_MACHINE_TYPES) + return false; + + if (data.cl_type <= CLOUD_NONE || (data.cl_type >= CLOUD_RANDOM + && data.cl_type != CLOUD_DEBUGGING)) + return false; + + if (data.size < 1 || data.power < 1) + return false; + + return true; +} + +int num_fogs_for_place(int level_number, const level_id &place) +{ + if (level_number == -1) + { + switch(place.level_type) + { + case LEVEL_DUNGEON: + level_number = absdungeon_depth(place.branch, place.depth); + break; + case LEVEL_ABYSS: + level_number = 51; + break; + case LEVEL_PANDEMONIUM: + level_number = 52; + break; + default: + level_number = you.your_level; + } + } + + switch(place.level_type) + { + case LEVEL_DUNGEON: + { + Branch &branch = branches[place.branch]; + ASSERT((branch.num_fogs_function == NULL + && branch.rand_fog_function == NULL) + || (branch.num_fogs_function != NULL + && branch.rand_fog_function != NULL)); + + if (branch.num_fogs_function == NULL) + return 0; + + return branch.num_fogs_function(level_number); + } + case LEVEL_ABYSS: + return fogs_abyss_number(level_number); + case LEVEL_PANDEMONIUM: + return fogs_pan_number(level_number); + case LEVEL_LABYRINTH: + return fogs_lab_number(level_number); + default: + return 0; + } + + return 0; +} + +fog_machine_data random_fog_for_place(int level_number, const level_id &place) +{ + fog_machine_data data = {NUM_FOG_MACHINE_TYPES, CLOUD_NONE, -1, -1}; + + if (level_number == -1) + { + switch(place.level_type) + { + case LEVEL_DUNGEON: + level_number = absdungeon_depth(place.branch, place.depth); + break; + case LEVEL_ABYSS: + level_number = 51; + break; + case LEVEL_PANDEMONIUM: + level_number = 52; + break; + default: + level_number = you.your_level; + } + } + + switch(place.level_type) + { + case LEVEL_DUNGEON: + { + Branch &branch = branches[place.branch]; + ASSERT(branch.num_fogs_function != NULL + && branch.rand_fog_function != NULL); + fog_machine_data data; + + branch.rand_fog_function(level_number, data); + return data; + } + case LEVEL_ABYSS: + return fogs_abyss_type(level_number); + case LEVEL_PANDEMONIUM: + return fogs_pan_type(level_number); + case LEVEL_LABYRINTH: + return fogs_lab_type(level_number); + default: + ASSERT(false); + return data; + } + + ASSERT(false); + return data; +} + +int fogs_pan_number(int level_number) +{ + return 0; +} + +fog_machine_data fogs_pan_type(int level_number) +{ + fog_machine_data data = {NUM_FOG_MACHINE_TYPES, CLOUD_NONE, -1, -1}; + + return data; +} + +int fogs_abyss_number(int level_number) +{ + return 0; +} + +fog_machine_data fogs_abyss_type(int level_number) +{ + fog_machine_data data = {NUM_FOG_MACHINE_TYPES, CLOUD_NONE, -1, -1}; + + return data; +} + +int fogs_lab_number(int level_number) +{ + return 0; +} + +fog_machine_data fogs_lab_type(int level_number) +{ + fog_machine_data data = {NUM_FOG_MACHINE_TYPES, CLOUD_NONE, -1, -1}; + + return data; +} //////////////////////////////////////////////////////////////////////// // cloud_struct diff --git a/crawl-ref/source/cloud.h b/crawl-ref/source/cloud.h index 157aa1932c..0cee66ca0d 100644 --- a/crawl-ref/source/cloud.h +++ b/crawl-ref/source/cloud.h @@ -13,6 +13,7 @@ #define CLOUD_H #include "externs.h" +#include "travel.h" enum fog_machine_type { @@ -22,6 +23,14 @@ enum fog_machine_type NUM_FOG_MACHINE_TYPES }; +struct fog_machine_data +{ + fog_machine_type fm_type; + cloud_type cl_type; + int size; + int power; +}; + cloud_type random_smoke_type(); void delete_cloud( int cloud ); @@ -40,4 +49,22 @@ int steam_cloud_damage(const cloud_struct &cloud); void place_fog_machine(fog_machine_type fm_type, cloud_type cl_type, int x, int y, int size, int power); +void place_fog_machine(fog_machine_data data, int x, int y); + +bool valid_fog_machine_data(fog_machine_data data); + +int num_fogs_for_place(int level_number = -1, + const level_id &place = level_id::current()); +fog_machine_data random_fog_for_place(int level_number = -1, + const level_id &place = level_id::current()); + +int fogs_pan_number(int level_number = -1); +fog_machine_data fogs_pan_type(int level_number = -1); + +int fogs_abyss_number(int level_number = -1); +fog_machine_data fogs_abyss_type(int level_number = -1); + +int fogs_lab_number(int level_number = -1); +fog_machine_data fogs_lab_type(int level_number = -1); + #endif diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index abeb5e4ad5..7a124183fe 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -34,6 +34,7 @@ #include "AppHdr.h" #include "abyss.h" #include "branch.h" +#include "cloud.h" #include "defines.h" #include "enum.h" #include "externs.h" @@ -137,6 +138,7 @@ static void place_minivaults(const std::string &tag = "", int fewest = -1, int most = -1, bool force = false); static void place_traps( int level_number ); +static void place_fog_machines( int level_number ); static void prepare_swamp(); static void prepare_shoals( int level_number ); static void prepare_water( int level_number ); @@ -982,8 +984,8 @@ static void build_dungeon_level(int level_number, int level_type) if (dgn_level_vetoed) return; - if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) - place_traps(level_number); + place_traps(level_number); + place_fog_machines(level_number); // place items builder_items(level_number, level_type, num_items_wanted(level_number)); @@ -2057,53 +2059,13 @@ static void builder_extras( int level_number, int level_type ) } } -// Also checks you.where_are_you! -static trap_type random_trap_for_level(int level_number) -{ - trap_type type = TRAP_DART; - - if ((random2(1 + level_number) > 1) && one_chance_in(4)) - type = TRAP_NEEDLE; - if (random2(1 + level_number) > 3) - type = TRAP_SPEAR; - if (random2(1 + level_number) > 5) - type = TRAP_AXE; - - // Note we're boosting arrow trap numbers by moving it - // down the list, and making spear and axe traps rarer. - if (type == TRAP_DART? - random2(1 + level_number) > 2 - : one_chance_in(7)) - type = TRAP_ARROW; - - if ((type == TRAP_DART || type == TRAP_ARROW) && one_chance_in(15)) - type = TRAP_NET; - - if (random2(1 + level_number) > 7) - type = TRAP_BOLT; - if (random2(1 + level_number) > 11) - type = TRAP_BLADE; - - if ((random2(1 + level_number) > 14 && one_chance_in(3)) - || (player_in_branch( BRANCH_HALL_OF_ZOT ) && coinflip())) - { - type = TRAP_ZOT; - } - - if (one_chance_in(50) && is_valid_shaft_level()) - type = TRAP_SHAFT; - if (one_chance_in(20)) - type = TRAP_TELEPORT; - if (one_chance_in(40)) - type = TRAP_ALARM; - - return (type); -} - static void place_traps(int level_number) { int i; - int num_traps = random2avg(9, 2); + int num_traps = num_traps_for_place(level_number); + + ASSERT(num_traps >= 0); + ASSERT(num_traps <= MAX_TRAPS); for (i = 0; i < num_traps; i++) { @@ -2120,13 +2082,51 @@ static void place_traps(int level_number) while (grd[env.trap[i].x][env.trap[i].y] != DNGN_FLOOR && --tries > 0); + if (tries <= 0) + break; + trap_type &trap_type = env.trap[i].type; - trap_type = random_trap_for_level(level_number); + trap_type = random_trap_for_place(level_number); grd[env.trap[i].x][env.trap[i].y] = DNGN_UNDISCOVERED_TRAP; } // end "for i" } // end place_traps() +static void place_fog_machines(int level_number) +{ + int i; + int num_fogs = num_fogs_for_place(level_number); + + ASSERT(num_fogs >= 0); + + for (i = 0; i < num_fogs; i++) + { + fog_machine_data data = random_fog_for_place(level_number); + + if (!valid_fog_machine_data(data)) + { + mpr("Invalid fog machine data, bailing.", MSGCH_DIAGNOSTICS); + return; + } + + int tries = 200; + int x, y; + dungeon_feature_type feat; + do + { + x = random2(GXM); + y = random2(GYM); + feat = grd[x][y]; + } + while (feat <= DNGN_MAXWALL && --tries > 0); + + if (tries <= 0) + break; + + place_fog_machine(data, x, y); + } // end "for i" +} // end place_traps() + static void place_specific_feature(dungeon_feature_type feat) { int sx, sy; @@ -4265,7 +4265,7 @@ static int vault_grid( vault_placement &place, else if (f.trap >= 0) { const trap_type trap = - f.trap == TRAP_INDEPTH? random_trap_for_level(level_number) + f.trap == TRAP_INDEPTH? random_trap_for_place(level_number) : static_cast<trap_type>(f.trap); place_specific_trap(vx, vy, trap); @@ -4341,7 +4341,7 @@ static int vault_grid( vault_placement &place, place_specific_trap(vx, vy, TRAP_RANDOM); break; case '~': - place_specific_trap(vx, vy, random_trap_for_level(level_number)); + place_specific_trap(vx, vy, random_trap_for_place(level_number)); break; } diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 24e3d1737a..8604af903b 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -1494,33 +1494,6 @@ bool go_berserk(bool intentional) return true; } // end go_berserk() -bool is_valid_shaft_level() -{ - if (you.level_type != LEVEL_DUNGEON) - return (false); - - // Don't generate shafts in branches where teleport control - // is prevented. Prevents player from going down levels without - // reaching stairs, and also keeps player from getting stuck - // on lower levels with the innability to use teleport control to - // get back up. - if (testbits(get_branch_flags(), LFLAG_NO_TELE_CONTROL)) - { - return (false); - } - - int depth = subdungeon_depth(you.where_are_you, you.your_level); - - // When generating levels, don't place a shaft on the level - // immediately above the bottom of a branch if that branch is - // significantly more dangerous than normal. - int min_delta = 1; - if (env.turns_on_level == -1 && your_branch().dangerous_bottom_level) - min_delta = 2; - - return ((your_branch().depth - depth) >= min_delta); -} - bool is_damaging_cloud(cloud_type type) { switch (type) diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 0dee017b67..460c76e403 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -123,7 +123,4 @@ bool scramble(void); bool interrupt_cmd_repeat( activity_interrupt_type ai, const activity_interrupt_data &at ); -////////////////////////////////////////////////////////////////////// -bool is_valid_shaft_level(); - #endif diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index 299f5d277b..b44543425f 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -16,6 +16,7 @@ #include "traps.h" #include "beam.h" +#include "branch.h" #include "direct.h" #include "it_use2.h" #include "items.h" @@ -25,6 +26,7 @@ #include "mon-util.h" #include "monstuff.h" #include "ouch.h" +#include "place.h" #include "player.h" #include "randart.h" #include "skills.h" @@ -925,3 +927,195 @@ trap_type trap_type_at_xy(int x, int y) return (idx == -1? NUM_TRAPS : env.trap[idx].type); } +bool is_valid_shaft_level(const level_id &place) +{ + if (place.level_type != LEVEL_DUNGEON) + return (false); + + // Don't generate shafts in branches where teleport control + // is prevented. Prevents player from going down levels without + // reaching stairs, and also keeps player from getting stuck + // on lower levels with the innability to use teleport control to + // get back up. + if (testbits(get_branch_flags(place.branch), LFLAG_NO_TELE_CONTROL)) + { + return (false); + } + + const Branch &branch = branches[place.branch]; + + // When generating levels, don't place a shaft on the level + // immediately above the bottom of a branch if that branch is + // significantly more dangerous than normal. + int min_delta = 1; + if (env.turns_on_level == -1 && branch.dangerous_bottom_level) + min_delta = 2; + + return ((branch.depth - place.depth) >= min_delta); +} + +static int num_traps_default(int level_number, const level_id &place) +{ + return random2avg(9, 2); +} + +int num_traps_for_place(int level_number, const level_id &place) +{ + if (level_number == -1) + { + switch(place.level_type) + { + case LEVEL_DUNGEON: + level_number = absdungeon_depth(place.branch, place.depth); + break; + case LEVEL_ABYSS: + level_number = 51; + break; + case LEVEL_PANDEMONIUM: + level_number = 52; + break; + default: + level_number = you.your_level; + } + } + + switch(place.level_type) + { + case LEVEL_DUNGEON: + if (branches[place.branch].num_traps_function != NULL) + return branches[place.branch].num_traps_function(level_number); + else + return num_traps_default(level_number, place); + case LEVEL_ABYSS: + return traps_abyss_number(level_number); + case LEVEL_PANDEMONIUM: + return traps_pan_number(level_number); + case LEVEL_LABYRINTH: + case LEVEL_PORTAL_VAULT: + ASSERT(false); + break; + default: + return 0; + } + + return 0; +} + +static trap_type random_trap_default(int level_number, const level_id &place) +{ + trap_type type = TRAP_DART; + + if ((random2(1 + level_number) > 1) && one_chance_in(4)) + type = TRAP_NEEDLE; + if (random2(1 + level_number) > 3) + type = TRAP_SPEAR; + if (random2(1 + level_number) > 5) + type = TRAP_AXE; + + // Note we're boosting arrow trap numbers by moving it + // down the list, and making spear and axe traps rarer. + if (type == TRAP_DART? + random2(1 + level_number) > 2 + : one_chance_in(7)) + type = TRAP_ARROW; + + if ((type == TRAP_DART || type == TRAP_ARROW) && one_chance_in(15)) + type = TRAP_NET; + + if (random2(1 + level_number) > 7) + type = TRAP_BOLT; + if (random2(1 + level_number) > 11) + type = TRAP_BLADE; + + if ((random2(1 + level_number) > 14 && one_chance_in(3)) + || (place.branch == BRANCH_HALL_OF_ZOT && + place.level_type == LEVEL_DUNGEON && coinflip())) + { + type = TRAP_ZOT; + } + + if (one_chance_in(50) && is_valid_shaft_level(place)) + type = TRAP_SHAFT; + if (one_chance_in(20)) + type = TRAP_TELEPORT; + if (one_chance_in(40)) + type = TRAP_ALARM; + + return (type); +} + +trap_type random_trap_for_place(int level_number, const level_id &place) +{ + if (level_number == -1) + { + switch(place.level_type) + { + case LEVEL_DUNGEON: + level_number = absdungeon_depth(place.branch, place.depth); + break; + case LEVEL_ABYSS: + level_number = 51; + break; + case LEVEL_PANDEMONIUM: + level_number = 52; + break; + default: + level_number = you.your_level; + } + } + + switch(place.level_type) + { + case LEVEL_DUNGEON: + if (branches[place.branch].rand_trap_function != NULL) + return branches[place.branch].rand_trap_function(level_number); + else + return random_trap_default(level_number, place); + case LEVEL_ABYSS: + return traps_abyss_type(level_number); + case LEVEL_PANDEMONIUM: + return traps_pan_type(level_number); + case LEVEL_LABYRINTH: + case LEVEL_PORTAL_VAULT: + ASSERT(false); + break; + default: + return random_trap_default(level_number, place); + } + return NUM_TRAPS; +} + +int traps_zero_number(int level_number) +{ + return 0; +} + +int traps_pan_number(int level_number) +{ + return num_traps_default(level_number, level_id(LEVEL_PANDEMONIUM)); +} + +trap_type traps_pan_type(int level_number) +{ + return random_trap_default(level_number, level_id(LEVEL_PANDEMONIUM)); +} + +int traps_abyss_number(int level_number) +{ + return num_traps_default(level_number, level_id(LEVEL_ABYSS)); +} + +trap_type traps_abyss_type(int level_number) +{ + return random_trap_default(level_number, level_id(LEVEL_ABYSS)); +} + +int traps_lab_number(int level_number) +{ + return num_traps_default(level_number, level_id(LEVEL_LABYRINTH)); +} + +trap_type traps_lab_type(int level_number) +{ + return random_trap_default(level_number, level_id(LEVEL_LABYRINTH)); +} diff --git a/crawl-ref/source/traps.h b/crawl-ref/source/traps.h index c86041840e..1853cf5313 100644 --- a/crawl-ref/source/traps.h +++ b/crawl-ref/source/traps.h @@ -14,6 +14,7 @@ #define TRAPS_H #include "enum.h" +#include "travel.h" struct dist; struct bolt; @@ -63,4 +64,22 @@ dungeon_feature_type trap_category(trap_type type); int trap_at_xy(int x, int y); trap_type trap_type_at_xy(int x, int y); +bool is_valid_shaft_level(const level_id &place = level_id::current()); + +int num_traps_for_place(int level_number = -1, + const level_id &place = level_id::current()); +trap_type random_trap_for_place(int level_number = -1, + const level_id &place = level_id::current()); + +int traps_zero_number(int level_number = -1); + +int traps_pan_number(int level_number = -1); +trap_type traps_pan_type(int level_number = -1); + +int traps_abyss_number(int level_number = -1); +trap_type traps_abyss_type(int level_number = -1); + +int traps_lab_number(int level_number = -1); +trap_type traps_lab_type(int level_number = -1); + #endif |