diff options
Diffstat (limited to 'stone_soup/crawl-ref/source/dungeon.cc')
-rw-r--r-- | stone_soup/crawl-ref/source/dungeon.cc | 8641 |
1 files changed, 0 insertions, 8641 deletions
diff --git a/stone_soup/crawl-ref/source/dungeon.cc b/stone_soup/crawl-ref/source/dungeon.cc deleted file mode 100644 index 2c38be36da..0000000000 --- a/stone_soup/crawl-ref/source/dungeon.cc +++ /dev/null @@ -1,8641 +0,0 @@ -/* - * File: dungeon.cc - * Summary: Functions used when building new levels. - * Written by: Linley Henzell - * - * Modified for Crawl Reference by $Author$ on $Date$ - * - * Change History (most recent first): - * - * - * <9> 07-Aug-2001 MV clean up of give_item; distribution of - * wands, potions and scrolls - * underground rivers and lakes - * <8> 02-Apr-2001 gdl cleanup; nuked all globals - * <7> 06-Mar-2000 bwr reduced vorpal weapon freq, - * spellbooks now hold up to eight spells. - * <6> 11/06/99 cdl random3 -> random2 - * <5> 8/08/99 BWR Upped rarity of unique artefacts - * <4> 7/13/99 BWR Made pole arms of speed. - * <3> 5/22/99 BWR Made named artefact weapons - * rarer, Sword of Power esp. - * <2> 5/09/99 LRH Replaced some sanity checking code in - * spellbook_template with a corrected version - * using ASSERTs. - * <1> -/--/-- LRH Created - */ - -#include <stdlib.h> -#include <stdio.h> -#include <time.h> - -#include "AppHdr.h" -#include "abyss.h" -#include "defines.h" -#include "enum.h" -#include "externs.h" -#include "dungeon.h" -#include "itemname.h" -#include "itemprop.h" -#include "items.h" -#include "maps.h" -#include "misc.h" -#include "mon-util.h" -#include "mon-pick.h" -#include "monplace.h" -#include "player.h" -#include "randart.h" -#include "spl-book.h" -#include "stuff.h" -#include "wpn-misc.h" - -#define MAX_PIT_MONSTERS 10 - -struct pit_mons_def { - int type; - int rare; -}; - -struct spec_t { - bool created; - bool hooked_up; - int x1; - int y1; - int x2; - int y2; -}; - -typedef struct spec_t spec_room; - -// DUNGEON BUILDERS -static bool find_in_area(int sx, int sy, int ex, int ey, unsigned char feature); -static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2, - unsigned char floor=0, unsigned char wall=0, unsigned char avoid=0); -static void replace_area(int sx, int sy, int ex, int ey, unsigned char replace, - unsigned char feature); -static int builder_by_type(int level_number, char level_type); -static int builder_by_branch(int level_number); -static int builder_normal(int level_number, char level_type, spec_room &s); -static int builder_basic(int level_number); -static void builder_extras(int level_number, int level_type); -static void builder_items(int level_number, char level_type, int items_wanted); -static void builder_monsters(int level_number, char level_type, int mon_wanted); -static void place_specific_stair(unsigned char stair); -static void place_branch_entrances(int dlevel, char level_type); -static bool place_specific_trap(unsigned char spec_x, unsigned char spec_y, - unsigned char spec_type); -static void place_traps( int level_number ); -static void prepare_swamp(void); -static void prepare_water( int level_number ); -static void check_doors(void); -static void hide_doors(void); -static void make_trail(int xs, int xr, int ys, int yr,int corrlength, int intersect_chance, - int no_corr, unsigned char begin, unsigned char end=0); -static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel); -static void join_the_dots(unsigned char dotx1, unsigned char doty1, - unsigned char dotx2, unsigned char doty2, char forbid_x1, char forbid_y1, - char forbid_x2, char forbid_y2); -static void place_pool(unsigned char pool_type, unsigned char pool_x1, - unsigned char pool_y1, unsigned char pool_x2, - unsigned char pool_y2); -static void many_pools(unsigned char pool_type); - -#ifdef USE_RIVERS -static void build_river(unsigned char river_type); //mv -static void build_lake(unsigned char lake_type); //mv -#endif // USE_RIVERS - -static void spotty_level(bool seeded, int iterations, bool boxy); -static void bigger_room(void); -static void plan_main(int level_number, char force_plan); -static char plan_1(void); -static char plan_2(void); -static char plan_3(void); -static char plan_4(char forbid_x1, char forbid_y1, char forbid_x2, - char forbid_y2, unsigned char force_wall); -static char plan_5(void); -static char plan_6(int level_number); -static bool octa_room(spec_room &sr, int oblique_max, unsigned char type_floor); -static void labyrinth_level(int level_number); -static void box_room(int bx1, int bx2, int by1, int by2, int wall_type); -static int box_room_doors( int bx1, int bx2, int by1, int by2, int new_doors); -static void city_level(int level_number); -static void diamond_rooms(int level_number); - -// ITEM & SHOP FUNCTIONS -static void place_shops(int level_number); -static void place_spec_shop(int level_number, unsigned char shop_x, - unsigned char shop_y, unsigned char force_s_type); -static unsigned char item_in_shop(unsigned char shop_type); -static bool treasure_area(int level_number, unsigned char ta1_x, - unsigned char ta2_x, unsigned char ta1_y, - unsigned char ta2_y); -static int rare_weapon(int w_type); -static bool is_weapon_special(int the_weapon); -static void set_weapon_special(int the_weapon, int spwpn); -static void big_room(int level_number); -static void chequerboard(spec_room &sr, unsigned char - target, unsigned char floor1, unsigned char floor2); -static void roguey_level(int level_number, spec_room &sr); -static void morgue(spec_room &sr); - -// SPECIAL ROOM BUILDERS -static void special_room(int level_number, spec_room &sr); -static void specr_2(spec_room &sr); -static void beehive(spec_room &sr); -static void jelly_pit(int level_number, spec_room &sr); - -// VAULT FUNCTIONS -static void build_vaults(int level_number, int force_vault); -static void build_minivaults(int level_number, int force_vault); -static int vault_grid( int level_number, int vx, int vy, int altar_count, - FixedVector < char, 7 > &acq_item_class, - FixedVector < int, 7 > &mons_array, - char vgrid, int &initial_x, int &initial_y, - int force_vault, int &num_runes ); - -// ALTAR FUNCTIONS -static int pick_an_altar(void); -static void place_altar(void); - -static bool got_curare_roll(const int item_level) -{ - return one_chance_in(item_level > 27? 6 : - item_level < 2 ? 15 : - (364 - 7 * item_level) / 25); -} - -/* - ************************************************** - * * - * BEGIN PUBLIC FUNCTIONS * - * * - ************************************************** -*/ - -// Determines if this feature blocks movement. -bool feat_blocks_movement(int feature) -{ - return (feature == DNGN_ROCK_WALL || - feature == DNGN_STONE_WALL || - feature == DNGN_METAL_WALL || - feature == DNGN_SECRET_DOOR || - feature == DNGN_GREEN_CRYSTAL_WALL || - feature == DNGN_ORCISH_IDOL || - feature == DNGN_WAX_WALL || - feature == DNGN_PERMAROCK_WALL || - feature == DNGN_SILVER_STATUE || - feature == DNGN_GRANITE_STATUE || - feature == DNGN_ORANGE_CRYSTAL_STATUE); -} - -void builder(int level_number, char level_type) -{ - int i; // generic loop variable - int x,y; // generic map loop variables - - // srandom(time(NULL)); - - // blank level with DNGN_ROCK_WALL - make_box(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,DNGN_ROCK_WALL); - - // delete all traps - for (i = 0; i < MAX_TRAPS; i++) - env.trap[i].type = TRAP_UNASSIGNED; - - // initialize all items - for (i = 0; i < MAX_ITEMS; i++) - init_item( i ); - - // reset all monsters - for (i = 0; i < MAX_MONSTERS; i++) - menv[i].type = -1; - - // unlink all monsters and items from the grid - for(x=0; x<GXM; x++) - { - for(y=0; y<GYM; y++) - { - mgrd[x][y] = NON_MONSTER; - igrd[x][y] = NON_ITEM; - } - } - - // reset all shops - for (unsigned char shcount = 0; shcount < 5; shcount++) - { - env.shop[shcount].type = SHOP_UNASSIGNED; - } - - int skip_build; - - skip_build = builder_by_type(level_number, level_type); - if (skip_build < 0) - return; - - if (skip_build == 0) - { - skip_build = builder_by_branch(level_number); - - if (skip_build < 0) - return; - } - - spec_room sr = { false, false, 0, 0, 0, 0 }; - - if (skip_build == 0) - { - // do 'normal' building. Well, except for the swamp. - if (!player_in_branch( BRANCH_SWAMP )) - skip_build = builder_normal(level_number, level_type, sr); - - if (skip_build == 0) - { - skip_build = builder_basic(level_number); - if (skip_build == 0) - builder_extras(level_number, level_type); - } - } - - // hook up the special room (if there is one, and it hasn't - // been hooked up already in roguey_level() - if (sr.created && !sr.hooked_up) - specr_2(sr); - - // now place items, monster, gates, etc. - // stairs must exist by this point. Some items and monsters - // already exist. - - // time to make the swamp {dlb}: - if (player_in_branch( BRANCH_SWAMP )) - prepare_swamp(); - - // figure out how many 'normal' monsters we should place - int mon_wanted = 0; - if (level_type == LEVEL_ABYSS - || player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) - { - mon_wanted = 0; - } - else - { - mon_wanted = roll_dice( 3, 10 ); - - if (player_in_hell()) - mon_wanted += roll_dice( 3, 8 ); - else if (player_in_branch( BRANCH_HALL_OF_BLADES )) - mon_wanted += roll_dice( 6, 8 ); - - // unlikely - now only possible in HoB {dlb} 10mar2000 - if (mon_wanted > 60) - mon_wanted = 60; - } - - place_branch_entrances( level_number, level_type ); - - check_doors(); - - if (!player_in_branch( BRANCH_DIS ) && !player_in_branch( BRANCH_VAULTS )) - hide_doors(); - - if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) - place_traps(level_number); - - int items_wanted = 3 + roll_dice( 3, 11 ); - - if (level_number > 5 && one_chance_in(500 - 5 * level_number)) - items_wanted = 10 + random2avg( 90, 2 ); // rich level! - - // change pre-rock (105) to rock, and pre-floor (106) to floor - replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_WALL, DNGN_ROCK_WALL ); - replace_area( 0,0,GXM-1,GYM-1, DNGN_BUILDER_SPECIAL_FLOOR, DNGN_FLOOR ); - - // place items - builder_items(level_number, level_type, items_wanted); - - // place monsters - builder_monsters(level_number, level_type, mon_wanted); - - // place shops, if appropriate - if (player_in_branch( BRANCH_MAIN_DUNGEON ) - || player_in_branch( BRANCH_ORCISH_MINES ) - || player_in_branch( BRANCH_ELVEN_HALLS ) - || player_in_branch( BRANCH_LAIR ) - || player_in_branch( BRANCH_VAULTS ) - || player_in_branch( BRANCH_SNAKE_PIT ) - || player_in_branch( BRANCH_SWAMP )) - { - place_shops(level_number); - } - - // If level part of Dis -> all walls metal; - // If part of vaults -> walls depend on level; - // If part of crypt -> all walls stone: - if (player_in_branch( BRANCH_DIS ) - || player_in_branch( BRANCH_VAULTS ) - || player_in_branch( BRANCH_CRYPT )) - { - // always the case with Dis {dlb} - unsigned char vault_wall = DNGN_METAL_WALL; - - if (player_in_branch( BRANCH_VAULTS )) - { - vault_wall = DNGN_ROCK_WALL; - - if (level_number > you.branch_stairs[STAIRS_VAULTS] + 2) - vault_wall = DNGN_STONE_WALL; - - if (level_number > you.branch_stairs[STAIRS_VAULTS] + 4) - vault_wall = DNGN_METAL_WALL; - - if (level_number > you.branch_stairs[STAIRS_VAULTS] + 6 - && one_chance_in(10)) - { - vault_wall = DNGN_GREEN_CRYSTAL_WALL; - } - } - else if (player_in_branch( BRANCH_CRYPT )) - { - vault_wall = DNGN_STONE_WALL; - } - - replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,vault_wall); - } - - // Top level of branch levels - replaces up stairs - // with stairs back to dungeon or wherever: - for (i = 0; i< 30; i++) - { - if (you.branch_stairs[i] == 0) - break; - - if (level_number == you.branch_stairs[i] + 1 - && level_type == LEVEL_DUNGEON - && you.where_are_you == BRANCH_ORCISH_MINES + i) - { - for (x = 1; x < GXM; x++) - { - for (y = 1; y < GYM; y++) - { - if (grd[x][y] >= DNGN_STONE_STAIRS_UP_I - && grd[x][y] <= DNGN_ROCK_STAIRS_UP) - { - grd[x][y] = DNGN_RETURN_FROM_ORCISH_MINES + i; - } - } - } - } - } - - // bottom level of branch - replaces down stairs with up ladders: - for (i = 0; i < 30; i++) - { - if (level_number == you.branch_stairs[i] + branch_depth(i) - && level_type == LEVEL_DUNGEON - && you.where_are_you == BRANCH_ORCISH_MINES + i) - { - for (x = 1; x < GXM; x++) - { - for (y = 1; y < GYM; y++) - { - if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I - && grd[x][y] <= DNGN_ROCK_STAIRS_DOWN) - { - grd[x][y] = DNGN_ROCK_STAIRS_UP; - } - } - } - } - } - - if (player_in_branch( BRANCH_CRYPT )) - { - if (one_chance_in(3)) - mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 ); - - if (one_chance_in(7)) - mons_place( MONS_CURSE_SKULL, BEH_SLEEP, MHITNOT, false, 0, 0 ); - } - - if (player_in_branch( BRANCH_ORCISH_MINES ) && one_chance_in(5)) - place_altar(); - - // hall of blades (1 level deal) - no down staircases, thanks! - if (player_in_branch( BRANCH_HALL_OF_BLADES )) - { - for (x = 1; x < GXM; x++) - { - for (y = 1; y < GYM; y++) - { - if (grd[x][y] >= DNGN_STONE_STAIRS_DOWN_I - && grd[x][y] <= DNGN_ROCK_STAIRS_UP) - { - grd[x][y] = DNGN_FLOOR; - } - } - } - } - - link_items(); - - if (!player_in_branch(BRANCH_COCYTUS) && !player_in_branch(BRANCH_SWAMP)) - prepare_water( level_number ); -} // end builder() - -// Returns item slot or NON_ITEM if it fails -int items( int allow_uniques, // not just true-false, - // because of BCR acquirement hack - int force_class, // desired OBJECTS class {dlb} - int force_type, // desired SUBTYPE - enum varies by OBJ - bool dont_place, // don't randomly place item on level - int item_level, // level of the item, can differ from global - int item_race ) // weapon / armour racial categories - // item_race also gives type of rune! -{ - int temp_rand = 0; // probability determination {dlb} - int range_charges = 0; // for OBJ_WANDS charge count {dlb} - int temp_value = 0; // temporary value storage {dlb} - int loopy = 0; // just another loop variable {dlb} - int count = 0; // just another loop variable {dlb} - - int race_plus = 0; - int race_plus2 = 0; - int x_pos, y_pos; - - int quant = 0; - - FixedVector < int, SPELLBOOK_SIZE > fpass; - int icky = 0; - int p = 0; - - // find an emtpy slot for the item (with culling if required) - p = get_item_slot(10); - if (p == NON_ITEM) - return (NON_ITEM); - - // clear all properties except mitm.base_type <used in switch below> {dlb}: - mitm[p].sub_type = 0; - mitm[p].flags = 0; - mitm[p].special = 0; - mitm[p].plus = 0; - mitm[p].plus2 = 0; - mitm[p].x = 0; - mitm[p].y = 0; - mitm[p].link = NON_ITEM; - mitm[p].slot = 0; - mitm[p].orig_monnum = 0; - mitm[p].orig_place = 0; - - // cap item_level unless an acquirement-level item {dlb}: - if (item_level > 50 && item_level != MAKE_GOOD_ITEM) - item_level = 50; - - // determine base_type for item generated {dlb}: - if (force_class != OBJ_RANDOM) - mitm[p].base_type = force_class; - else - { - // nice and large for subtle differences {dlb} - temp_rand = random2(10000); - - mitm[p].base_type = ((temp_rand < 50) ? OBJ_STAVES : // 0.50% - (temp_rand < 200) ? OBJ_BOOKS : // 1.50% - (temp_rand < 450) ? OBJ_JEWELLERY :// 2.50% - (temp_rand < 800) ? OBJ_WANDS : // 3.50% - (temp_rand < 1500) ? OBJ_FOOD : // 7.00% - (temp_rand < 2500) ? OBJ_ARMOUR : // 10.00% - (temp_rand < 3500) ? OBJ_WEAPONS : // 10.00% - (temp_rand < 4500) ? OBJ_POTIONS : // 10.00% - (temp_rand < 6000) ? OBJ_MISSILES : // 15.00% - (temp_rand < 8000) ? OBJ_SCROLLS // 20.00% - : OBJ_GOLD); // 20.00% - - // misc items placement wholly dependent upon current depth {dlb}: - if (item_level > 7 && (20 + item_level) >= random2(3500)) - mitm[p].base_type = OBJ_MISCELLANY; - - if (item_level < 7 - && (mitm[p].base_type == OBJ_BOOKS - || mitm[p].base_type == OBJ_STAVES - || mitm[p].base_type == OBJ_WANDS) - && random2(7) >= item_level) - { - mitm[p].base_type = coinflip() ? OBJ_POTIONS : OBJ_SCROLLS; - } - } - - // determine sub_type accordingly {dlb}: - switch (mitm[p].base_type) - { - case OBJ_WEAPONS: - // generate initial weapon subtype using weighted function -- - // indefinite loop now more evident and fewer array lookups {dlb}: - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - else - { - if (random2(20) < 20 - item_level) - { - // these are the common/low level weapon types - temp_rand = random2(12); - - mitm[p].sub_type = ((temp_rand == 0) ? WPN_KNIFE : - (temp_rand == 1) ? WPN_QUARTERSTAFF : - (temp_rand == 2) ? WPN_SLING : - (temp_rand == 3) ? WPN_SPEAR : - (temp_rand == 4) ? WPN_HAND_AXE : - (temp_rand == 5) ? WPN_DAGGER : - (temp_rand == 6) ? WPN_MACE : - (temp_rand == 7) ? WPN_DAGGER : - (temp_rand == 8) ? WPN_CLUB : - (temp_rand == 9) ? WPN_HAMMER : - (temp_rand == 10) ? WPN_WHIP - : WPN_SABRE); - } - else if (item_level > 6 && random2(100) < (10 + item_level) - && one_chance_in(30)) - { - // place the rare_weapon() == 0 weapons - // - // this replaced the infinite loop (wasteful) -- may need - // to make into its own function to allow ease of tweaking - // distribution {dlb}: - temp_rand = random2(10); - - mitm[p].sub_type = ((temp_rand == 9) ? WPN_LAJATANG : - (temp_rand == 8) ? WPN_DEMON_BLADE : - (temp_rand == 7) ? WPN_DEMON_TRIDENT : - (temp_rand == 6) ? WPN_DEMON_WHIP : - (temp_rand == 5) ? WPN_DOUBLE_SWORD : - (temp_rand == 4) ? WPN_EVENINGSTAR : - (temp_rand == 3) ? WPN_EXECUTIONERS_AXE : - (temp_rand == 2) ? WPN_KATANA : - (temp_rand == 1) ? WPN_QUICK_BLADE - /*(temp_rand == 0)*/: WPN_TRIPLE_SWORD); - } - else - { - // pick a weapon based on rarity - for (;;) - { - temp_value = (unsigned char) random2(NUM_WEAPONS); - - if (rare_weapon(temp_value) >= random2(10) + 1) - { - mitm[p].sub_type = temp_value; - break; - } - } - } - } - - if (allow_uniques) - { - // Note there is nothing to stop randarts being reproduced, - // except vast improbability. - if (mitm[p].sub_type != WPN_CLUB && item_level > 2 - && random2(2000) <= 100 + (item_level * 3) && coinflip()) - { - if (you.level_type != LEVEL_ABYSS - && you.level_type != LEVEL_PANDEMONIUM - && one_chance_in(50)) - { - icky = find_okay_unrandart( OBJ_WEAPONS, force_type ); - - if (icky != -1) - { - quant = 1; - make_item_unrandart( mitm[p], icky ); - break; - } - } - - make_item_randart( mitm[p] ); - mitm[p].plus = 0; - mitm[p].plus2 = 0; - mitm[p].plus += random2(7); - mitm[p].plus2 += random2(7); - - if (one_chance_in(3)) - mitm[p].plus += random2(7); - - if (one_chance_in(3)) - mitm[p].plus2 += random2(7); - - if (one_chance_in(9)) - mitm[p].plus -= random2(7); - - if (one_chance_in(9)) - mitm[p].plus2 -= random2(7); - - quant = 1; - - if (one_chance_in(4)) - { - do_curse_item( mitm[p] ); - mitm[p].plus = -random2(6); - mitm[p].plus2 = -random2(6); - } - else if ((mitm[p].plus < 0 || mitm[p].plus2 < 0) - && !one_chance_in(3)) - { - do_curse_item( mitm[p] ); - } - break; - } - - if (item_level > 6 - && random2(3000) <= 30 + (item_level * 3) && one_chance_in(12)) - { - if (make_item_fixed_artefact( mitm[p], (item_level == 51) )) - break; - } - } - - ASSERT(!is_fixed_artefact(mitm[p]) && !is_random_artefact(mitm[p])); - - if (item_level == MAKE_GOOD_ITEM - && force_type != OBJ_RANDOM - && (mitm[p].sub_type == WPN_CLUB || mitm[p].sub_type == WPN_SLING)) - { - mitm[p].sub_type = WPN_LONG_SWORD; - } - - quant = 1; - - mitm[p].plus = 0; - mitm[p].plus2 = 0; - mitm[p].special = SPWPN_NORMAL; - - if (item_race == MAKE_ITEM_RANDOM_RACE && coinflip()) - { - switch (mitm[p].sub_type) - { - case WPN_CLUB: - if (coinflip()) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case WPN_MACE: - case WPN_FLAIL: - case WPN_SPIKED_FLAIL: - case WPN_GREAT_MACE: - case WPN_DIRE_FLAIL: - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case WPN_MORNINGSTAR: - case WPN_HAMMER: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case WPN_DAGGER: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_SHORT_SWORD: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_FALCHION: - if (one_chance_in(5)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_LONG_SWORD: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (coinflip()) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_GREAT_SWORD: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case WPN_SCIMITAR: - if (coinflip()) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case WPN_WAR_AXE: - case WPN_HAND_AXE: - case WPN_BROAD_AXE: - case WPN_BATTLEAXE: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (coinflip()) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case WPN_SPEAR: - case WPN_TRIDENT: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_HALBERD: - case WPN_GLAIVE: - case WPN_EXECUTIONERS_AXE: - case WPN_LOCHABER_AXE: - if (one_chance_in(5)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case WPN_QUICK_BLADE: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_KATANA: - case WPN_LAJATANG: - case WPN_KNIFE: - case WPN_SLING: - set_equip_race( mitm[p], ISFLAG_NO_RACE ); - set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL ); - break; - - case WPN_BOW: - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (coinflip()) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_LONGBOW: - set_equip_race( mitm[p], one_chance_in(3) ? ISFLAG_ELVEN - : ISFLAG_NO_RACE ); - break; - - case WPN_CROSSBOW: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case WPN_HAND_CROSSBOW: - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case WPN_BLOWGUN: - if (one_chance_in(10)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - } - } - - // fine, but out-of-order relative to mitm[].special ordering {dlb} - switch (item_race) - { - case MAKE_ITEM_ELVEN: - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case MAKE_ITEM_DWARVEN: - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case MAKE_ITEM_ORCISH: - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - } - - // if we allow acquirement-type items to be orcish, then - // there's a good chance that we'll just strip them of - // their ego type at the bottom of this function. -- bwr - if (item_level == MAKE_GOOD_ITEM - && get_equip_race( mitm[p] ) == ISFLAG_ORCISH) - { - set_equip_race( mitm[p], ISFLAG_NO_RACE ); - } - - switch (get_equip_race( mitm[p] )) - { - case ISFLAG_ORCISH: - if (coinflip()) - race_plus--; - if (coinflip()) - race_plus2++; - break; - - case ISFLAG_ELVEN: - race_plus += random2(3); - break; - - case ISFLAG_DWARVEN: - if (coinflip()) - race_plus++; - if (coinflip()) - race_plus2++; - break; - } - - mitm[p].plus += race_plus; - mitm[p].plus2 += race_plus2; - - if ((random2(200) <= 50 + item_level - || item_level == MAKE_GOOD_ITEM - || is_demonic(mitm[p].sub_type)) - // nobody would bother enchanting a club - && mitm[p].sub_type != WPN_CLUB - && mitm[p].sub_type != WPN_GIANT_CLUB - && mitm[p].sub_type != WPN_GIANT_SPIKED_CLUB) - { - count = 0; - - do - { - if (random2(300) <= 100 + item_level - || item_level == MAKE_GOOD_ITEM - || is_demonic( mitm[p].sub_type )) - { - // note: this doesn't guarantee special enchantment - switch (mitm[p].sub_type) - { - case WPN_EVENINGSTAR: - if (coinflip()) - set_weapon_special(p, SPWPN_DRAINING); - // **** intentional fall through here **** - case WPN_MORNINGSTAR: - if (one_chance_in(4)) - set_weapon_special(p, SPWPN_VENOM); - - if (one_chance_in(4)) - { - set_weapon_special(p, (coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(20)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - // **** intentional fall through here **** - case WPN_MACE: - case WPN_GREAT_MACE: - if ((mitm[p].sub_type == WPN_MACE - || mitm[p].sub_type == WPN_GREAT_MACE) - && one_chance_in(4)) - { - set_weapon_special(p, SPWPN_DISRUPTION); - } - // **** intentional fall through here **** - case WPN_FLAIL: - case WPN_SPIKED_FLAIL: - case WPN_DIRE_FLAIL: - case WPN_HAMMER: - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(3) && - (!is_weapon_special(p) || one_chance_in(5))) - set_weapon_special(p, SPWPN_VORPAL); - - if (one_chance_in(4)) - set_weapon_special(p, SPWPN_HOLY_WRATH); - - if (one_chance_in(3)) - set_weapon_special(p, SPWPN_PROTECTION); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_DRAINING); - break; - - - case WPN_DAGGER: - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(3)) - set_weapon_special(p, SPWPN_VENOM); - // **** intentional fall through here **** - - case WPN_SHORT_SWORD: - case WPN_SABRE: - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_ELECTROCUTION); - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_PROTECTION); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_ORC_SLAYING); - - if (one_chance_in(8)) - { - set_weapon_special(p,(coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(12)) - set_weapon_special(p, SPWPN_HOLY_WRATH); - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_DRAINING); - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_SPEED); - - if (one_chance_in(6)) - set_weapon_special(p, SPWPN_VENOM); - break; - - case WPN_FALCHION: - case WPN_LONG_SWORD: - if (one_chance_in(12)) - set_weapon_special(p, SPWPN_VENOM); - // **** intentional fall through here **** - case WPN_SCIMITAR: - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(7)) - set_weapon_special(p, SPWPN_SPEED); - // **** intentional fall through here **** - case WPN_GREAT_SWORD: - case WPN_DOUBLE_SWORD: - case WPN_TRIPLE_SWORD: - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(5)) - { - set_weapon_special(p,(coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(7)) - set_weapon_special(p, SPWPN_PROTECTION); - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_ORC_SLAYING); - - if (one_chance_in(12)) - set_weapon_special(p, SPWPN_DRAINING); - - if (one_chance_in(7)) - set_weapon_special(p, SPWPN_ELECTROCUTION); - - if (one_chance_in(4)) - set_weapon_special(p, SPWPN_HOLY_WRATH); - - if (one_chance_in(4) - && (!is_weapon_special(p) || one_chance_in(3))) - { - set_weapon_special(p, SPWPN_VORPAL); - } - break; - - - case WPN_WAR_AXE: - case WPN_BROAD_AXE: - case WPN_BATTLEAXE: - case WPN_EXECUTIONERS_AXE: - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_HOLY_WRATH); - - if (one_chance_in(14)) - set_weapon_special(p, SPWPN_DRAINING); - // **** intentional fall through here **** - case WPN_HAND_AXE: - if (one_chance_in(30)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(3) - && (!is_weapon_special(p) || one_chance_in(5))) - { - set_weapon_special(p, SPWPN_VORPAL); - } - - if (one_chance_in(6)) - set_weapon_special(p, SPWPN_ORC_SLAYING); - - if (one_chance_in(4)) - { - set_weapon_special(p, (coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(8)) - set_weapon_special(p, SPWPN_ELECTROCUTION); - - if (one_chance_in(12)) - set_weapon_special(p, SPWPN_VENOM); - - break; - - case WPN_WHIP: - if (one_chance_in(20)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(6)) - { - set_weapon_special(p, (coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(6)) - set_weapon_special(p, SPWPN_VENOM); - - if (coinflip()) - set_weapon_special(p, SPWPN_REACHING); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_SPEED); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_ELECTROCUTION); - break; - - case WPN_HALBERD: - case WPN_GLAIVE: - case WPN_SCYTHE: - case WPN_TRIDENT: - case WPN_LOCHABER_AXE: - if (one_chance_in(30)) - set_weapon_special(p, SPWPN_HOLY_WRATH); - - if (one_chance_in(4)) - set_weapon_special(p, SPWPN_PROTECTION); - // **** intentional fall through here **** - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_SPEED); - // **** intentional fall through here **** - case WPN_SPEAR: - if (one_chance_in(25)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - - if (one_chance_in(20)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(5) && - (!is_weapon_special(p) || one_chance_in(6))) - set_weapon_special(p, SPWPN_VORPAL); - - if (one_chance_in(6)) - set_weapon_special(p, SPWPN_ORC_SLAYING); - - if (one_chance_in(6)) - { - set_weapon_special(p, (coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(6)) - set_weapon_special(p, SPWPN_VENOM); - - if (one_chance_in(3)) - set_weapon_special(p, SPWPN_REACHING); - break; - - - case WPN_SLING: - case WPN_HAND_CROSSBOW: - if (coinflip()) - break; - // **** possible intentional fall through here **** - case WPN_BOW: - case WPN_LONGBOW: - case WPN_CROSSBOW: - { - const int tmp = random2(1000); - - set_weapon_special( p, (tmp < 375) ? SPWPN_FLAMING : - (tmp < 750) ? SPWPN_FREEZING : - (tmp < 920) ? SPWPN_PROTECTION : - (tmp < 980) ? SPWPN_VORPAL - : SPWPN_SPEED ); - break; - } - case WPN_BLOWGUN: - if (one_chance_in(7)) - set_weapon_special(p, SPWPN_VENOM); - break; - - // quarterstaff - not powerful, as this would make - // the 'staves' skill just too good - case WPN_QUARTERSTAFF: - if (one_chance_in(30)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(20)) - set_weapon_special(p, SPWPN_DISTORTION); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_SPEED); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_VORPAL); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_PROTECTION); - break; - - - case WPN_DEMON_TRIDENT: - case WPN_DEMON_WHIP: - case WPN_DEMON_BLADE: - set_equip_race( mitm[p], ISFLAG_NO_RACE ); - - if (one_chance_in(10)) - set_weapon_special(p, SPWPN_PAIN); - - if (one_chance_in(3) - && (mitm[p].sub_type == WPN_DEMON_WHIP - || mitm[p].sub_type == WPN_DEMON_TRIDENT)) - { - set_weapon_special(p, SPWPN_REACHING); - } - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_DRAINING); - - if (one_chance_in(5)) - { - set_weapon_special(p, (coinflip() ? SPWPN_FLAMING - : SPWPN_FREEZING)); - } - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_ELECTROCUTION); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_VAMPIRICISM); - - if (one_chance_in(5)) - set_weapon_special(p, SPWPN_VENOM); - break; - - case WPN_BLESSED_BLADE: // special gift of TSO - set_weapon_special( p, SPWPN_HOLY_WRATH ); - break; - - // unlisted weapons have no associated, standard ego-types {dlb} - default: - break; - } - } // end if specially enchanted - - count++; - } - while (item_level == MAKE_GOOD_ITEM - && mitm[p].special == SPWPN_NORMAL - && count < 5); - - // if acquired item still not ego... enchant it up a bit. - if (item_level == MAKE_GOOD_ITEM && mitm[p].special == SPWPN_NORMAL) - { - mitm[p].plus += 2 + random2(3); - mitm[p].plus2 += 2 + random2(3); - } - - const int chance = (item_level == MAKE_GOOD_ITEM) ? 200 - : item_level; - - // odd-looking, but this is how the algorithm compacts {dlb}: - for (loopy = 0; loopy < 4; loopy++) - { - mitm[p].plus += random2(3); - - if (random2(350) > 20 + chance) - break; - } - - // odd-looking, but this is how the algorithm compacts {dlb}: - for (loopy = 0; loopy < 4; loopy++) - { - mitm[p].plus2 += random2(3); - - if (random2(500) > 50 + chance) - break; - } - } - else - { - if (one_chance_in(12)) - { - do_curse_item( mitm[p] ); - mitm[p].plus -= random2(4); - mitm[p].plus2 -= random2(4); - - // clear specials {dlb} - set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL ); - } - } - - // value was "0" comment said "orc" so I went with comment {dlb} - if (get_equip_race(mitm[p]) == ISFLAG_ORCISH) - { - // no holy wrath or slay orc and 1/2 the time no-ego - const int brand = get_weapon_brand( mitm[p] ); - if (brand == SPWPN_HOLY_WRATH - || brand == SPWPN_ORC_SLAYING - || (brand != SPWPN_NORMAL && coinflip())) - { - // this makes no sense {dlb} - // Probably a remnant of the old code which used - // to decrement this when the electric attack happened -- bwr - // if (brand == SPWPN_ELECTROCUTION) - // mitm[p].plus = 0; - - set_item_ego_type( mitm[p], OBJ_WEAPONS, SPWPN_NORMAL ); - } - } - - if ((((is_random_artefact( mitm[p] ) - || get_weapon_brand( mitm[p] ) != SPWPN_NORMAL) - && !one_chance_in(10)) - || ((mitm[p].plus != 0 || mitm[p].plus2 != 0) - && one_chance_in(3))) - && mitm[p].sub_type != WPN_CLUB - && mitm[p].sub_type != WPN_GIANT_CLUB - && mitm[p].sub_type != WPN_GIANT_SPIKED_CLUB - && get_equip_desc(mitm[p]) == 0 - && get_equip_race(mitm[p]) == 0) - { - set_equip_desc( mitm[p], (coinflip() ? ISFLAG_GLOWING - : ISFLAG_RUNED) ); - } - break; - - case OBJ_MISSILES: - quant = 0; - mitm[p].plus = 0; - mitm[p].special = SPMSL_NORMAL; - - temp_rand = random2(20); - mitm[p].sub_type = (temp_rand < 6) ? MI_STONE : // 30 % - (temp_rand < 10) ? MI_DART : // 20 % - (temp_rand < 14) ? MI_ARROW : // 20 % - (temp_rand < 18) ? MI_BOLT // 20 % - : MI_NEEDLE; // 10 % - - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - - // no fancy rocks -- break out before we get to racial/special stuff - if (mitm[p].sub_type == MI_LARGE_ROCK) - { - quant = 2 + random2avg(5,2); - break; - } - else if (mitm[p].sub_type == MI_STONE) - { - quant = 1 + random2(9) + random2(12) + random2(15) + random2(12); - break; - } - - // set racial type: - switch (item_race) - { - case MAKE_ITEM_ELVEN: - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case MAKE_ITEM_DWARVEN: - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case MAKE_ITEM_ORCISH: - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - - case MAKE_ITEM_RANDOM_RACE: - if ((mitm[p].sub_type == MI_ARROW - || mitm[p].sub_type == MI_DART) - && one_chance_in(4)) - { - // elven - not for bolts, though - set_equip_race( mitm[p], ISFLAG_ELVEN ); - } - - if ((mitm[p].sub_type == MI_ARROW - || mitm[p].sub_type == MI_BOLT - || mitm[p].sub_type == MI_DART) - && one_chance_in(4)) - { - set_equip_race( mitm[p], ISFLAG_ORCISH ); - } - - if ((mitm[p].sub_type == MI_DART - || mitm[p].sub_type == MI_BOLT) - && one_chance_in(6)) - { - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - } - - if (mitm[p].sub_type == MI_NEEDLE) - { - if (one_chance_in(10)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - } - break; - } - - // note that needles can only be poisoned - // - // Actually, it'd be really nice if there where - // some paralysis or slowing poison needles, just - // so that blowguns have some added utility over - // the other launchers/throwing weapons. -- bwr - if (mitm[p].sub_type == MI_NEEDLE - && (item_level == MAKE_GOOD_ITEM || !one_chance_in(5))) - { - const int pois = - item_level == MAKE_GOOD_ITEM || - got_curare_roll(item_level) - ? SPMSL_CURARE : SPMSL_POISONED_II; - set_item_ego_type( mitm[p], OBJ_MISSILES, pois ); - } - else - { - // decide specials: - if (item_level == MAKE_GOOD_ITEM) - temp_rand = random2(150); - else - temp_rand = random2(2000 - 55 * item_level); - - set_item_ego_type( mitm[p], OBJ_MISSILES, - (temp_rand < 60) ? SPMSL_FLAME : - (temp_rand < 120) ? SPMSL_ICE : - (temp_rand < 150) ? SPMSL_POISONED_II - : SPMSL_NORMAL ); - } - - // orcish ammo gets poisoned a lot more often -- in the original - // code it was poisoned every time!? - if (get_equip_race(mitm[p]) == ISFLAG_ORCISH && one_chance_in(3)) - set_item_ego_type( mitm[p], OBJ_MISSILES, SPMSL_POISONED_II ); - - // reduced quantity if special - if (get_ammo_brand( mitm[p] ) != SPMSL_NORMAL ) - quant = 1 + random2(9) + random2(12) + random2(12); - else - quant = 1 + random2(9) + random2(12) + random2(15) + random2(12); - - if (10 + item_level >= random2(100)) - mitm[p].plus += random2(5); - - // elven arrows and dwarven bolts are quality items - if ((get_equip_race(mitm[p]) == ISFLAG_ELVEN - && mitm[p].sub_type == MI_ARROW) - || (get_equip_race(mitm[p]) == ISFLAG_DWARVEN - && mitm[p].sub_type == MI_BOLT)) - { - mitm[p].plus += random2(3); - } - break; - - case OBJ_ARMOUR: - quant = 1; - - mitm[p].plus = 0; - mitm[p].plus2 = 0; - mitm[p].special = SPARM_NORMAL; - - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - else - { - mitm[p].sub_type = random2(3); - - if (random2(35) <= item_level + 10) - { - mitm[p].sub_type = random2(5); - if (one_chance_in(4)) - mitm[p].sub_type = ARM_ANIMAL_SKIN; - } - - if (random2(60) <= item_level + 10) - mitm[p].sub_type = random2(8); - - if (10 + item_level >= random2(400) && one_chance_in(20)) - mitm[p].sub_type = ARM_DRAGON_HIDE + random2(7); - - if (10 + item_level >= random2(500) && one_chance_in(20)) - { - mitm[p].sub_type = ARM_STEAM_DRAGON_HIDE + random2(11); - - if (mitm[p].sub_type == ARM_ANIMAL_SKIN && one_chance_in(20)) - mitm[p].sub_type = ARM_CRYSTAL_PLATE_MAIL; - } - - // secondary armours: - if (one_chance_in(5)) - { - mitm[p].sub_type = ARM_SHIELD + random2(5); - - if (mitm[p].sub_type == ARM_SHIELD) // 33.3% - { - if (coinflip()) - mitm[p].sub_type = ARM_BUCKLER; // 50.0% - else if (one_chance_in(3)) - mitm[p].sub_type = ARM_LARGE_SHIELD; // 16.7% - } - } - } - - if (mitm[p].sub_type == ARM_HELMET) - { - set_helmet_type( mitm[p], THELM_HELMET ); - set_helmet_desc( mitm[p], THELM_DESC_PLAIN ); - - if (one_chance_in(3)) - set_helmet_type( mitm[p], random2( THELM_NUM_TYPES ) ); - - if (one_chance_in(3)) - set_helmet_random_desc( mitm[p] ); - } - - if (allow_uniques == 1 - && item_level > 2 - && random2(2000) <= (100 + item_level * 3) - && coinflip()) - { - if ((you.level_type != LEVEL_ABYSS - && you.level_type != LEVEL_PANDEMONIUM) - && one_chance_in(50)) - { - icky = find_okay_unrandart(OBJ_ARMOUR); - if (icky != -1) - { - quant = 1; - make_item_unrandart( mitm[p], icky ); - break; - } - } - - hide2armour(mitm[p]); - - // mitm[p].special = SPARM_RANDART_II + random2(4); - make_item_randart( mitm[p] ); - mitm[p].plus = 0; - - if (mitm[p].sub_type == ARM_BOOTS - && one_chance_in(10)) - { - mitm[p].sub_type = - coinflip()? ARM_NAGA_BARDING - : ARM_CENTAUR_BARDING; - } - - mitm[p].plus += random2(4); - - if (one_chance_in(5)) - mitm[p].plus += random2(4); - - if (one_chance_in(6)) - mitm[p].plus -= random2(8); - - quant = 1; - - if (one_chance_in(5)) - { - do_curse_item( mitm[p] ); - mitm[p].plus = -random2(6); - } - else if (mitm[p].plus < 0 && !one_chance_in(3)) - { - do_curse_item( mitm[p] ); - } - break; - } - - mitm[p].plus = 0; - - if (item_race == MAKE_ITEM_RANDOM_RACE && coinflip()) - { - switch (mitm[p].sub_type) - { - case ARM_SHIELD: // shield - must do special things for this! - case ARM_BUCKLER: - case ARM_LARGE_SHIELD: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (one_chance_in(3)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case ARM_CLOAK: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case ARM_GLOVES: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case ARM_NAGA_BARDING: - case ARM_CENTAUR_BARDING: - case ARM_BOOTS: - if (mitm[p].sub_type == ARM_BOOTS) - { - if (one_chance_in(4)) - { - mitm[p].sub_type = ARM_NAGA_BARDING; - break; - } - - if (one_chance_in(4)) - { - mitm[p].sub_type = ARM_CENTAUR_BARDING; - break; - } - } - - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - break; - - case ARM_HELMET: - if (get_helmet_type(mitm[p]) == THELM_CAP - || get_helmet_type(mitm[p]) == THELM_WIZARD_HAT) - { - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - } - else - { - // helms and helmets - if (one_chance_in(8)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - if (one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - } - break; - - case ARM_ROBE: - if (one_chance_in(4)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case ARM_RING_MAIL: - case ARM_SCALE_MAIL: - case ARM_CHAIN_MAIL: - case ARM_SPLINT_MAIL: - case ARM_BANDED_MAIL: - case ARM_PLATE_MAIL: - if (mitm[p].sub_type <= ARM_CHAIN_MAIL && one_chance_in(6)) - set_equip_race( mitm[p], ISFLAG_ELVEN ); - if (mitm[p].sub_type >= ARM_RING_MAIL && one_chance_in(5)) - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (one_chance_in(5)) - set_equip_race( mitm[p], ISFLAG_ORCISH ); - - default: // skins, hides, crystal plate are always plain - break; - } - } - - switch (item_race) - { - case MAKE_ITEM_ELVEN: - set_equip_race( mitm[p], ISFLAG_ELVEN ); - break; - - case MAKE_ITEM_DWARVEN: - set_equip_race( mitm[p], ISFLAG_DWARVEN ); - if (coinflip()) - mitm[p].plus++; - break; - - case MAKE_ITEM_ORCISH: - set_equip_race( mitm[p], ISFLAG_ORCISH ); - break; - } - - - if (50 + item_level >= random2(250) - || item_level == MAKE_GOOD_ITEM - || (mitm[p].sub_type == ARM_HELMET - && get_helmet_type(mitm[p]) == THELM_WIZARD_HAT)) - { - mitm[p].plus += random2(3); - - if (mitm[p].sub_type <= ARM_PLATE_MAIL && 20 + item_level >= random2(300)) - mitm[p].plus += random2(3); - - if (30 + item_level >= random2(350) - && (item_level == MAKE_GOOD_ITEM - || (!get_equip_race(mitm[p]) == ISFLAG_ORCISH - || (mitm[p].sub_type <= ARM_PLATE_MAIL && coinflip())))) - { - switch (mitm[p].sub_type) - { - case ARM_SHIELD: // shield - must do special things for this! - case ARM_LARGE_SHIELD: - case ARM_BUCKLER: - { - const int tmp = random2(1000); - - set_item_ego_type( mitm[p], OBJ_ARMOUR, - (tmp < 40) ? SPARM_RESISTANCE : - (tmp < 160) ? SPARM_FIRE_RESISTANCE : - (tmp < 280) ? SPARM_COLD_RESISTANCE : - (tmp < 400) ? SPARM_POISON_RESISTANCE : - (tmp < 520) ? SPARM_POSITIVE_ENERGY - : SPARM_PROTECTION ); - break; // prot - //break; - } - case ARM_CLOAK: - if (get_equip_race(mitm[p]) == ISFLAG_DWARVEN) - break; - - switch (random2(4)) - { - case 0: - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_POISON_RESISTANCE ); - break; - - case 1: - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_DARKNESS ); - break; - case 2: - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE ); - break; - case 3: - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_PRESERVATION ); - break; - } - break; - - case ARM_HELMET: - if (get_helmet_type(mitm[p]) == THELM_WIZARD_HAT && coinflip()) - { - if (one_chance_in(3)) - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE ); - } - else - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_INTELLIGENCE ); - } - } - else - { - set_item_ego_type( mitm[p], OBJ_ARMOUR, - coinflip() ? SPARM_SEE_INVISIBLE - : SPARM_INTELLIGENCE ); - } - break; - - case ARM_GLOVES: - set_item_ego_type( mitm[p], OBJ_ARMOUR, - coinflip() ? SPARM_DEXTERITY - : SPARM_STRENGTH ); - break; - - case ARM_BOOTS: - case ARM_NAGA_BARDING: - case ARM_CENTAUR_BARDING: - { - const int tmp = random2(600) - + 200 * (mitm[p].sub_type != ARM_BOOTS); - - set_item_ego_type( mitm[p], OBJ_ARMOUR, - (tmp < 200) ? SPARM_RUNNING : - (tmp < 400) ? SPARM_LEVITATION : - (tmp < 600) ? SPARM_STEALTH : - (tmp < 700) ? SPARM_COLD_RESISTANCE - : SPARM_FIRE_RESISTANCE ); - break; - } - - case ARM_ROBE: - switch (random2(4)) - { - case 0: - set_item_ego_type( mitm[p], OBJ_ARMOUR, - coinflip() ? SPARM_COLD_RESISTANCE - : SPARM_FIRE_RESISTANCE ); - break; - - case 1: - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE ); - break; - - case 2: - set_item_ego_type( mitm[p], OBJ_ARMOUR, - coinflip() ? SPARM_POSITIVE_ENERGY - : SPARM_RESISTANCE ); - break; - case 3: - if (force_type != OBJ_RANDOM - || is_random_artefact( mitm[p] ) - || get_armour_ego_type( mitm[p] ) != SPARM_NORMAL - || random2(50) > 10 + item_level) - { - break; - } - - set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_ARCHMAGI ); - break; - } - break; - - default: // other body armours: - set_item_ego_type( mitm[p], OBJ_ARMOUR, - coinflip() ? SPARM_COLD_RESISTANCE - : SPARM_FIRE_RESISTANCE ); - - if (one_chance_in(9)) - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_POSITIVE_ENERGY ); - } - - if (one_chance_in(5)) - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_MAGIC_RESISTANCE ); - } - - if (one_chance_in(5)) - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_POISON_RESISTANCE ); - } - - if (mitm[p].sub_type == ARM_PLATE_MAIL - && one_chance_in(15)) - { - set_item_ego_type( mitm[p], - OBJ_ARMOUR, SPARM_PONDEROUSNESS ); - mitm[p].plus += 3 + random2(4); - } - break; - } - } - } - else if (one_chance_in(12)) - { - // mitm[p].plus = (coinflip() ? 99 : 98); // 98? 99? - do_curse_item( mitm[p] ); - - if (one_chance_in(5)) - mitm[p].plus -= random2(3); - - set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_NORMAL ); - } - - // if not given a racial type, and special, give shiny/runed/etc desc. - if (get_equip_race(mitm[p]) == 0 - && get_equip_desc(mitm[p]) == 0 - && (((is_random_artefact(mitm[p]) - || get_armour_ego_type( mitm[p] ) != SPARM_NORMAL) - && !one_chance_in(10)) - || (mitm[p].plus != 0 && one_chance_in(3)))) - { - switch (random2(3)) - { - case 0: - set_equip_desc( mitm[p], ISFLAG_GLOWING ); - break; - - case 1: - set_equip_desc( mitm[p], ISFLAG_RUNED ); - break; - - case 2: - default: - set_equip_desc( mitm[p], ISFLAG_EMBROIDERED_SHINY ); - break; - } - } - - // Make sure you don't get a hide from acquirement (since that - // would be an enchanted item which somehow didn't get converted - // into armour). - if (item_level == MAKE_GOOD_ITEM) - hide2armour(mitm[p]); // what of animal hides? {dlb} - - // skin armours + Crystal PM don't get special enchantments - // or species, but can be randarts - if (mitm[p].sub_type >= ARM_DRAGON_HIDE - && mitm[p].sub_type <= ARM_SWAMP_DRAGON_ARMOUR) - { - set_equip_race( mitm[p], ISFLAG_NO_RACE ); - set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_NORMAL ); - } - break; - - case OBJ_WANDS: - // determine sub_type: - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - else - { - mitm[p].sub_type = random2( NUM_WANDS ); - - // Adjusted distribution here -- bwr - // Wands used to be uniform (5.26% each) - // - // Now: - // invis, hasting, healing (1.11% each) - // fireball, teleportaion (3.74% each) - // others (6.37% each) - if ((mitm[p].sub_type == WAND_INVISIBILITY - || mitm[p].sub_type == WAND_HASTING - || mitm[p].sub_type == WAND_HEALING) - || ((mitm[p].sub_type == WAND_FIREBALL - || mitm[p].sub_type == WAND_TELEPORTATION) - && coinflip())) - { - mitm[p].sub_type = random2( NUM_WANDS ); - } - } - - // determine upper bound on charges: - range_charges = ((mitm[p].sub_type == WAND_HEALING - || mitm[p].sub_type == WAND_HASTING - || mitm[p].sub_type == WAND_INVISIBILITY) ? 8 : - (mitm[p].sub_type == WAND_FLAME - || mitm[p].sub_type == WAND_FROST - || mitm[p].sub_type == WAND_MAGIC_DARTS - || mitm[p].sub_type == WAND_RANDOM_EFFECTS) ? 28 - : 16); - - // generate charges randomly: - mitm[p].plus = random2avg(range_charges, 3); - // - // set quantity to one: - quant = 1; - break; - - case OBJ_FOOD: // this can be parsed out {dlb} - // determine sub_type: - if (force_type == OBJ_RANDOM) - { - temp_rand = random2(1000); - - mitm[p].sub_type = - ((temp_rand >= 750) ? FOOD_MEAT_RATION : // 25.00% chance - (temp_rand >= 450) ? FOOD_BREAD_RATION :// 30.00% chance - (temp_rand >= 350) ? FOOD_PEAR : // 10.00% chance - (temp_rand >= 250) ? FOOD_APPLE : // 10.00% chance - (temp_rand >= 150) ? FOOD_CHOKO : // 10.00% chance - (temp_rand >= 140) ? FOOD_CHEESE : // 1.00% chance - (temp_rand >= 130) ? FOOD_PIZZA : // 1.00% chance - (temp_rand >= 120) ? FOOD_SNOZZCUMBER : // 1.00% chance - (temp_rand >= 110) ? FOOD_APRICOT : // 1.00% chance - (temp_rand >= 100) ? FOOD_ORANGE : // 1.00% chance - (temp_rand >= 90) ? FOOD_BANANA : // 1.00% chance - (temp_rand >= 80) ? FOOD_STRAWBERRY : // 1.00% chance - (temp_rand >= 70) ? FOOD_RAMBUTAN : // 1.00% chance - (temp_rand >= 60) ? FOOD_LEMON : // 1.00% chance - (temp_rand >= 50) ? FOOD_GRAPE : // 1.00% chance - (temp_rand >= 40) ? FOOD_SULTANA : // 1.00% chance - (temp_rand >= 30) ? FOOD_LYCHEE : // 1.00% chance - (temp_rand >= 20) ? FOOD_BEEF_JERKY : // 1.00% chance - (temp_rand >= 10) ? FOOD_SAUSAGE : // 1.00% chance - (temp_rand >= 5) ? FOOD_HONEYCOMB // 0.50% chance - : FOOD_ROYAL_JELLY );// 0.50% chance - } - else - mitm[p].sub_type = force_type; - - // Happens with ghoul food acquirement -- use place_chunks() outherwise - if (mitm[p].sub_type == FOOD_CHUNK) - { - for (count = 0; count < 1000; count++) - { - temp_rand = random2( NUM_MONSTERS ); // random monster - temp_rand = mons_species( temp_rand ); // corpse base type - - if (mons_weight( temp_rand ) > 0) // drops a corpse - break; - } - - // set chunk flavour (default to common dungeon rat steaks): - mitm[p].plus = (count == 1000) ? MONS_RAT : temp_rand; - - // set duration - mitm[p].special = (10 + random2(11)) * 10; - } - - // determine quantity: - if (allow_uniques > 1) - quant = allow_uniques; - else - { - quant = 1; - - if (mitm[p].sub_type != FOOD_MEAT_RATION - && mitm[p].sub_type != FOOD_BREAD_RATION) - { - if (one_chance_in(80)) - quant += random2(3); - - if (mitm[p].sub_type == FOOD_STRAWBERRY - || mitm[p].sub_type == FOOD_GRAPE - || mitm[p].sub_type == FOOD_SULTANA) - { - quant += 3 + random2avg(15,2); - } - } - } - break; - - case OBJ_POTIONS: - quant = 1; - - if (one_chance_in(18)) - quant++; - - if (one_chance_in(25)) - quant++; - - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - else - { - temp_rand = random2(9); // general type of potion; - - switch (temp_rand) - { - case 0: - case 1: - case 2: - case 8: - // healing potions - if (one_chance_in(3)) - mitm[p].sub_type = POT_HEAL_WOUNDS; // 14.074% - else - mitm[p].sub_type = POT_HEALING; // 28.148% - - if (one_chance_in(20)) - mitm[p].sub_type = POT_CURE_MUTATION; // 2.222% - break; - - case 3: - case 4: - // enhancements - if (coinflip()) - mitm[p].sub_type = POT_SPEED; // 6.444% - else - mitm[p].sub_type = POT_MIGHT; // 6.444% - - if (one_chance_in(10)) - mitm[p].sub_type = POT_BERSERK_RAGE; // 1.432% - - if (one_chance_in(5)) - mitm[p].sub_type = POT_INVISIBILITY; // 3.580% - - if (one_chance_in(6)) - mitm[p].sub_type = POT_LEVITATION; // 3.580% - - if (one_chance_in(30)) - mitm[p].sub_type = POT_PORRIDGE; // 0.741% - break; - - case 5: - // gain ability - mitm[p].sub_type = POT_GAIN_STRENGTH + random2(3); // 1.125% - // or 0.375% each - - if (one_chance_in(10)) - mitm[p].sub_type = POT_EXPERIENCE; // 0.125% - - if (one_chance_in(10)) - mitm[p].sub_type = POT_MAGIC; // 0.139% - - if (!one_chance_in(8)) - mitm[p].sub_type = POT_RESTORE_ABILITIES; // 9.722% - - quant = 1; - break; - - case 6: - case 7: - // bad things - switch (random2(6)) - { - case 0: - case 4: - // is this not always the case? - no, level one is 0 {dlb} - if (item_level > 0) - { - mitm[p].sub_type = POT_POISON; // 6.475% - - if (item_level > 10 && one_chance_in(4)) - mitm[p].sub_type = POT_STRONG_POISON; - - break; - } - - /* **** intentional fall through **** */ // ignored for % - case 5: - if (item_level > 6) - { - mitm[p].sub_type = POT_MUTATION; // 3.237% - break; - } - - /* **** intentional fall through **** */ // ignored for % - case 1: - mitm[p].sub_type = POT_SLOWING; // 3.237% - break; - - case 2: - mitm[p].sub_type = POT_PARALYSIS; // 3.237% - break; - - case 3: - mitm[p].sub_type = POT_CONFUSION; // 3.237% - break; - - } - - if (one_chance_in(8)) - mitm[p].sub_type = POT_DEGENERATION; // 2.775% - - if (one_chance_in(1000)) // 0.022% - mitm[p].sub_type = POT_DECAY; - - break; - } - } - - mitm[p].plus = 0; - break; - - case OBJ_SCROLLS: - // determine sub_type: - if (force_type == OBJ_RANDOM) - { - // only used in certain cases {dlb} - int depth_mod = random2(1 + item_level); - - temp_rand = random2(920); - - mitm[p].sub_type = - ((temp_rand > 751) ? SCR_IDENTIFY : // 18.26% - (temp_rand > 629) ? SCR_REMOVE_CURSE : // 13.26% - (temp_rand > 554) ? SCR_TELEPORTATION : // 8.15% - (temp_rand > 494) ? SCR_DETECT_CURSE : // 6.52% - (temp_rand > 464) ? SCR_FEAR : // 3.26% - (temp_rand > 434) ? SCR_NOISE : // 3.26% - (temp_rand > 404) ? SCR_MAGIC_MAPPING : // 3.26% - (temp_rand > 374) ? SCR_FORGETFULNESS : // 3.26% - (temp_rand > 344) ? SCR_RANDOM_USELESSNESS :// 3.26% - (temp_rand > 314) ? SCR_CURSE_WEAPON : // 3.26% - (temp_rand > 284) ? SCR_CURSE_ARMOUR : // 3.26% - (temp_rand > 254) ? SCR_RECHARGING : // 3.26% - (temp_rand > 224) ? SCR_BLINKING : // 3.26% - (temp_rand > 194) ? SCR_PAPER : // 3.26% - (temp_rand > 164) ? SCR_ENCHANT_ARMOUR : // 3.26% - (temp_rand > 134) ? SCR_ENCHANT_WEAPON_I : // 3.26% - (temp_rand > 104) ? SCR_ENCHANT_WEAPON_II : // 3.26% - - // Crawl is kind to newbie adventurers {dlb}: - // yes -- these five are messy {dlb}: - // yes they are a hellish mess of tri-ops and long lines, - // this formating is somewhat better -- bwr - (temp_rand > 74) ? - ((item_level < 4) ? SCR_TELEPORTATION - : SCR_IMMOLATION) : // 3.26% - (temp_rand > 59) ? - ((depth_mod < 4) ? SCR_TELEPORTATION - : SCR_ACQUIREMENT) : // 1.63% - (temp_rand > 44) ? - ((depth_mod < 4) ? SCR_DETECT_CURSE - : SCR_SUMMONING) : // 1.63% - (temp_rand > 29) ? - ((depth_mod < 4) ? SCR_TELEPORTATION // 1.63% - : SCR_ENCHANT_WEAPON_III) : - (temp_rand > 14) ? - ((depth_mod < 7) ? SCR_DETECT_CURSE - : SCR_TORMENT) // 1.63% - // default: - : ((depth_mod < 7) ? SCR_TELEPORTATION // 1.63% - : SCR_VORPALISE_WEAPON)); - } - else - mitm[p].sub_type = force_type; - - // determine quantity: - temp_rand = random2(48); - - quant = ((temp_rand > 1 - || mitm[p].sub_type == SCR_VORPALISE_WEAPON - || mitm[p].sub_type == SCR_ENCHANT_WEAPON_III - || mitm[p].sub_type == SCR_ACQUIREMENT - || mitm[p].sub_type == SCR_TORMENT) ? 1 : // 95.83% - (temp_rand == 0) ? 2 // 2.08% - : 3); // 2.08% - mitm[p].plus = 0; - break; - - case OBJ_JEWELLERY: - // determine whether an unrandart will be generated {dlb}: - if (item_level > 2 - && you.level_type != LEVEL_ABYSS - && you.level_type != LEVEL_PANDEMONIUM - && random2(2000) <= 100 + (item_level * 3) - && one_chance_in(20)) - { - icky = find_okay_unrandart(OBJ_JEWELLERY); - - if (icky != -1) - { - quant = 1; - make_item_unrandart( mitm[p], icky ); - break; - } - } - - // otherwise, determine jewellery type {dlb}: - if (force_type == OBJ_RANDOM) - { - mitm[p].sub_type = (!one_chance_in(4) ? random2(24) // rings - : AMU_RAGE + random2(10)); - - // Adjusted distribution here -- bwr - if ((mitm[p].sub_type == RING_INVISIBILITY - || mitm[p].sub_type == RING_REGENERATION - || mitm[p].sub_type == RING_TELEPORT_CONTROL - || mitm[p].sub_type == RING_SLAYING) - && !one_chance_in(3)) - { - mitm[p].sub_type = random2(24); - } - } - else - mitm[p].sub_type = force_type; - - // quantity is always one {dlb}: - quant = 1; - - // everything begins as uncursed, unenchanted jewellery {dlb}: - mitm[p].plus = 0; - mitm[p].plus2 = 0; - - // set pluses for rings that require them {dlb}: - switch (mitm[p].sub_type) - { - case RING_PROTECTION: - case RING_STRENGTH: - case RING_SLAYING: - case RING_EVASION: - case RING_DEXTERITY: - case RING_INTELLIGENCE: - if (one_chance_in(5)) // 20% of such rings are cursed {dlb} - { - do_curse_item( mitm[p] ); - mitm[p].plus = (coinflip() ? -2 : -3); - - if (one_chance_in(3)) - mitm[p].plus -= random2(4); - } - else - { - mitm[p].plus += 1 + (one_chance_in(3) ? random2(3) - : random2avg(6, 2)); - } - break; - - default: - break; - } - - // rings of slaying also require that pluses2 be set {dlb}: - if (mitm[p].sub_type == RING_SLAYING) - { - if (item_cursed( mitm[p] ) && !one_chance_in(20)) - mitm[p].plus2 = -1 - random2avg(6, 2); - else - { - mitm[p].plus2 += 1 + (one_chance_in(3) ? random2(3) - : random2avg(6, 2)); - - if (random2(25) < 9) // 36% of such rings {dlb} - { - // make "ring of damage" - do_uncurse_item( mitm[p] ); - mitm[p].plus = 0; - mitm[p].plus2 += 2; - } - } - } - - // All jewellery base types should now work. -- bwr - if (allow_uniques == 1 && item_level > 2 - && random2(2000) <= 100 + (item_level * 3) && coinflip()) - { - make_item_randart( mitm[p] ); - break; - } - - // rings of hunger and teleportation are always cursed {dlb}: - if (mitm[p].sub_type == RING_HUNGER - || mitm[p].sub_type == RING_TELEPORTATION - || one_chance_in(50)) - { - do_curse_item( mitm[p] ); - } - break; - - case OBJ_BOOKS: - create_book: - do - { - mitm[p].sub_type = random2(NUM_BOOKS); - - if (book_rarity(mitm[p].sub_type) == 100) - continue; - - if (mitm[p].sub_type != BOOK_DESTRUCTION - && mitm[p].sub_type != BOOK_MANUAL) - { - if (one_chance_in(10)) - { - if (coinflip()) - mitm[p].sub_type = BOOK_WIZARDRY; - else - mitm[p].sub_type = BOOK_POWER; - } - - if (random2(item_level + 1) + 1 >= book_rarity(mitm[p].sub_type) - || one_chance_in(100)) - { - break; - } - else - { - mitm[p].sub_type = BOOK_DESTRUCTION; - continue; - } - } - } - while (mitm[p].sub_type == BOOK_DESTRUCTION - || mitm[p].sub_type == BOOK_MANUAL); - - if (book_rarity(mitm[p].sub_type) == 100) - goto create_book; - - mitm[p].special = random2(5); - - if (one_chance_in(10)) - mitm[p].special += random2(8) * 10; - - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - - quant = 1; - - // tome of destruction : rare! - if (force_type == BOOK_DESTRUCTION - || (random2(7000) <= item_level + 20 && item_level > 10 - && force_type == OBJ_RANDOM)) - { - mitm[p].sub_type = BOOK_DESTRUCTION; - } - - // skill manuals - also rare - // fixed to generate manuals for *all* extant skills - 14mar2000 {dlb} - if (force_type == BOOK_MANUAL - || (random2(4000) <= item_level + 20 && item_level > 6 - && force_type == OBJ_RANDOM)) - { - mitm[p].sub_type = BOOK_MANUAL; - - if (one_chance_in(4)) - { - mitm[p].plus = SK_SPELLCASTING - + random2(NUM_SKILLS - SK_SPELLCASTING); - } - else - { - mitm[p].plus = random2(SK_UNARMED_COMBAT); - - if (mitm[p].plus == SK_UNUSED_1) - mitm[p].plus = SK_UNARMED_COMBAT; - } - } - break; - - case OBJ_STAVES: // this can be parsed, too {dlb} - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - else - { - mitm[p].sub_type = random2(13); - - // top three non-spell staves are in separate block -- bwr - if (mitm[p].sub_type >= 10) - mitm[p].sub_type = STAFF_AIR + mitm[p].sub_type - 10; - - // spell staves - if (one_chance_in(20)) - mitm[p].sub_type = STAFF_SMITING + random2(10); - - if ((mitm[p].sub_type == STAFF_ENERGY - || mitm[p].sub_type == STAFF_CHANNELING) && one_chance_in(4)) - { - mitm[p].sub_type = coinflip() ? STAFF_WIZARDRY : STAFF_POWER; - } - } - - mitm[p].special = random2(NUM_STAVE_ADJ); - - if (item_is_rod( mitm[p] )) - { - mitm[p].plus2 = (9 + random2( MAX_ROD_CHARGE - 8 )) - * ROD_CHARGE_MULT; - mitm[p].plus = mitm[p].plus2; - } - - quant = 1; - break; - - case OBJ_ORBS: // always forced in current setup {dlb} - quant = 1; - - if (force_type != OBJ_RANDOM) - mitm[p].sub_type = force_type; - - // I think we only have one type of orb now, so ... {dlb} - set_unique_item_status( OBJ_ORBS, mitm[p].sub_type, UNIQ_EXISTS ); - break; - - // I think these must always be forced, too ... {dlb} - - case OBJ_MISCELLANY: //mv: rewrote with use of NUM_MISCELLANY (9 Aug 01) - if (force_type == OBJ_RANDOM) - { - do - mitm[p].sub_type = random2(NUM_MISCELLANY); - while //mv: never generated - ((mitm[p].sub_type == MISC_RUNE_OF_ZOT) - || (mitm[p].sub_type == MISC_HORN_OF_GERYON) - || (mitm[p].sub_type == MISC_PORTABLE_ALTAR_OF_NEMELEX) - // mv: others are possible but less often - // btw. chances of generating decks are almost the same as - // before, other chances are now distributed more steadily - || (mitm[p].sub_type == MISC_DECK_OF_POWER && !one_chance_in(12)) - || (mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS && !one_chance_in(3)) - || (mitm[p].sub_type == MISC_DECK_OF_TRICKS && !one_chance_in(3)) - || (mitm[p].sub_type == MISC_DECK_OF_WONDERS && !one_chance_in(3)) - ); - - // filling those silly empty boxes -- bwr - if (mitm[p].sub_type == MISC_EMPTY_EBONY_CASKET - && !one_chance_in(20)) - { - mitm[p].sub_type = MISC_BOX_OF_BEASTS; - } - } - else - { - mitm[p].sub_type = force_type; - } - - if (mitm[p].sub_type == MISC_DECK_OF_WONDERS - || mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS - || mitm[p].sub_type == MISC_DECK_OF_POWER) - { - mitm[p].plus = 4 + random2(10); - } - - if (mitm[p].sub_type == MISC_DECK_OF_TRICKS) - mitm[p].plus = 6 + random2avg(15, 2); - - if (mitm[p].sub_type == MISC_RUNE_OF_ZOT) - mitm[p].plus = item_race; - - quant = 1; - break; // mv: end of rewrote; - - // that is, everything turns to gold if not enumerated above, so ... {dlb} - default: - mitm[p].base_type = OBJ_GOLD; - - // Note that acquirement level gold gives much less than the - // price of a scroll of acquirement (520 gold). -- bwr - if (item_level == MAKE_GOOD_ITEM) - quant = 50 + random2avg(100, 2) + random2avg(100, 2); - else - quant = 1 + random2avg(19, 2) + random2(item_level); - break; - } - - mitm[p].quantity = quant; - - // should really only be used for monster inventories. - if (dont_place) - { - mitm[p].x = 0; - mitm[p].y = 0; - mitm[p].link = NON_ITEM; - } - else - { - do - { - x_pos = random2(GXM); - y_pos = random2(GYM); - } - while (grd[x_pos][y_pos] != DNGN_FLOOR); - - move_item_to_grid( &p, x_pos, y_pos ); - } - - item_colour( mitm[p] ); - - // Okay, this check should be redundant since the purpose of - // this function is to create valid items. Still, we're adding - // this safety for fear that a report of Trog giving a non-existant - // item might symbolize something more serious. -- bwr - return (is_valid_item( mitm[p] ) ? p : NON_ITEM); -} // end items() - - -void give_item(int mid, int level_number) //mv: cleanup+minor changes -{ - int temp_rand = 0; // probability determination {dlb} - - int bp = 0; - int thing_created = 0; - int hand_used = 0; // for Ettins etc. - int xitc = 0; - int xitt = 0; - - int iquan = 0; - // forces colour and quantity, too for intial weapons {dlb} - int force_item = 0; - - int item_race = MAKE_ITEM_RANDOM_RACE; - int give_level = level_number; - - //mv: THIS CODE DISTRIBUTES WANDS/SCROLLS/POTIONS - //(now only to uniques but it's easy to modify that) - //7 Aug 01 - - //mv - give scroll - - if (mons_is_unique( menv[mid].type ) && one_chance_in(3)) - { - thing_created = items(0, OBJ_SCROLLS, OBJ_RANDOM, true, give_level, 0); - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - menv[mid].inv[MSLOT_SCROLL] = thing_created; - } - - //mv - give wand - if (mons_is_unique( menv[mid].type ) && one_chance_in(5)) - { - thing_created = items(0, OBJ_WANDS, OBJ_RANDOM, true, give_level, 0); - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - menv[mid].inv[MSLOT_WAND] = thing_created; - } - - //mv - give potion - if (mons_is_unique( menv[mid].type ) && one_chance_in(3)) - { - thing_created = items(0, OBJ_POTIONS, OBJ_RANDOM, true, give_level, 0); - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - menv[mid].inv[MSLOT_POTION] = thing_created; - } - - - //end of DISTRIBUTE WANDS/POTIONS/SCROLLS CODE - - bp = get_item_slot(); - if (bp == NON_ITEM) - return; - - mitm[bp].quantity = 0; // set below if force_item, else we toss this item! - mitm[bp].plus = 0; - mitm[bp].plus2 = 0; - mitm[bp].special = 0; - mitm[bp].orig_place = 0; - mitm[bp].orig_monnum = 0; - - // this flags things to "goto give_armour" below ... {dlb} - mitm[bp].base_type = 101; - - if (menv[mid].type == MONS_DANCING_WEAPON - && player_in_branch( BRANCH_HALL_OF_BLADES )) - { - give_level = MAKE_GOOD_ITEM; - } - - // moved setting of quantity here to keep it in mind {dlb} - iquan = 1; - // I wonder if this is even used, given calls to item() {dlb} - - - switch (menv[mid].type) - { - case MONS_KOBOLD: - // a few of the smarter kobolds have blowguns. - if (one_chance_in(10) && level_number > 1) - { - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_BLOWGUN; - break; - } - // intentional fallthrough - case MONS_BIG_KOBOLD: - if (random2(5) < 3) // give hand weapon - { - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(5); - mitm[bp].sub_type = ((temp_rand > 2) ? WPN_DAGGER : // 40% - (temp_rand > 0) ? WPN_SHORT_SWORD // 40% - : WPN_CLUB); // 20% - } - else if (random2(5) < 2) // give darts - { - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_MISSILES; - mitm[bp].sub_type = MI_DART; - iquan = 1 + random2(5); - } - else - goto give_ammo; - break; - - case MONS_HOBGOBLIN: - if (one_chance_in(3)) - item_race = MAKE_ITEM_ORCISH; - - if (random2(5) < 3) // give hand weapon - { - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_CLUB; - } - else - goto give_ammo; - break; - - case MONS_GOBLIN: - if (one_chance_in(3)) - item_race = MAKE_ITEM_ORCISH; - - if (one_chance_in(12) && level_number > 1) - { - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].base_type = WPN_BLOWGUN; - break; - } - // deliberate fall through {dlb} - case MONS_JESSICA: - case MONS_IJYB: - if (random2(5) < 3) // < 1 // give hand weapon - { - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = (coinflip() ? WPN_DAGGER : WPN_CLUB); - } - else - goto give_ammo; - break; - - case MONS_WIGHT: - case MONS_NORRIS: - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = (one_chance_in(6) ? WPN_WAR_AXE + random2(4) - : WPN_MACE + random2(12)); - - if (coinflip()) - { - force_item = 1; - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].plus += 1 + random2(3); - mitm[bp].plus2 += 1 + random2(3); - - if (one_chance_in(5)) - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FREEZING ); - } - - if (one_chance_in(3)) - do_curse_item( mitm[bp] ); - break; - - case MONS_GNOLL: - case MONS_OGRE_MAGE: - case MONS_NAGA_WARRIOR: - case MONS_GREATER_NAGA: - case MONS_EDMUND: - case MONS_DUANE: - item_race = MAKE_ITEM_NO_RACE; - - if (!one_chance_in(5)) - { - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(5); - mitm[bp].sub_type = ((temp_rand > 2) ? WPN_SPEAR : // 40% - (temp_rand == 2) ? WPN_FLAIL : // 20% - (temp_rand == 1) ? WPN_HALBERD // 20% - : WPN_CLUB); // 20% - } - break; - - case MONS_ORC: - if (one_chance_in(15) && level_number > 1) - { - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].base_type = WPN_BLOWGUN; - break; - } - // deliberate fall through {gdl} - case MONS_ORC_PRIEST: - case MONS_TERENCE: - case MONS_DRACONIAN: - case MONS_DRACONIAN_ZEALOT: - if (!one_chance_in(5)) - { - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(240); - mitm[bp].sub_type = ((temp_rand > 209) ? WPN_DAGGER : //12.50% - (temp_rand > 179) ? WPN_CLUB : //12.50% - (temp_rand > 152) ? WPN_FLAIL : //11.25% - (temp_rand > 128) ? WPN_HAND_AXE : //10.00% - (temp_rand > 108) ? WPN_HAMMER : // 8.33% - (temp_rand > 88) ? WPN_HALBERD : // 8.33% - (temp_rand > 68) ? WPN_SHORT_SWORD : // 8.33% - (temp_rand > 48) ? WPN_MACE : // 8.33% - (temp_rand > 38) ? WPN_WHIP : // 4.17% - (temp_rand > 28) ? WPN_TRIDENT : // 4.17% - (temp_rand > 18) ? WPN_FALCHION : // 4.17% - (temp_rand > 8) ? WPN_MORNINGSTAR : // 4.17% - (temp_rand > 2) ? WPN_WAR_AXE // 2.50% - : WPN_SPIKED_FLAIL);// 1.25% - } - else - goto give_ammo; - break; - - case MONS_DEEP_ELF_FIGHTER: - case MONS_DEEP_ELF_HIGH_PRIEST: - case MONS_DEEP_ELF_KNIGHT: - case MONS_DEEP_ELF_PRIEST: - case MONS_DEEP_ELF_SOLDIER: - item_race = MAKE_ITEM_ELVEN; - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(100); - mitm[bp].sub_type = ((temp_rand > 79) ? WPN_LONG_SWORD : // 20% - (temp_rand > 59) ? WPN_SHORT_SWORD : // 20% - (temp_rand > 45) ? WPN_SCIMITAR : // 14% - (temp_rand > 31) ? WPN_MACE : // 14% - (temp_rand > 18) ? WPN_BOW : // 13% - (temp_rand > 5) ? WPN_HAND_CROSSBOW // 13% - : WPN_LONGBOW); // 6% - break; - - case MONS_DEEP_ELF_ANNIHILATOR: - case MONS_DEEP_ELF_CONJURER: - case MONS_DEEP_ELF_DEATH_MAGE: - case MONS_DEEP_ELF_DEMONOLOGIST: - case MONS_DEEP_ELF_MAGE: - case MONS_DEEP_ELF_SORCERER: - case MONS_DEEP_ELF_SUMMONER: - case MONS_DRACONIAN_SHIFTER: - case MONS_DRACONIAN_SCORCHER: - case MONS_DRACONIAN_ANNIHILATOR: - case MONS_DRACONIAN_CALLER: - item_race = MAKE_ITEM_ELVEN; - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(6); - mitm[bp].sub_type = ((temp_rand > 3) ? WPN_LONG_SWORD : // 2 in 6 - (temp_rand > 2) ? WPN_SHORT_SWORD :// 1 in 6 - (temp_rand > 1) ? WPN_SABRE : // 1 in 6 - (temp_rand > 0) ? WPN_DAGGER // 1 in 6 - : WPN_WHIP); // 1 in 6 - break; - - case MONS_ORC_WARRIOR: - case MONS_ORC_HIGH_PRIEST: - case MONS_BLORK_THE_ORC: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall-through {dlb} - case MONS_DANCING_WEAPON: // give_level may have been adjusted above - case MONS_FRANCES: - case MONS_FRANCIS: - case MONS_HAROLD: - case MONS_JOSEPH: - case MONS_LOUISE: - case MONS_MICHAEL: - case MONS_NAGA: - case MONS_NAGA_MAGE: - case MONS_RUPERT: - case MONS_SKELETAL_WARRIOR: - case MONS_WAYNE: - case MONS_PALE_DRACONIAN: - case MONS_RED_DRACONIAN: - case MONS_WHITE_DRACONIAN: - case MONS_GREEN_DRACONIAN: - case MONS_MOTTLED_DRACONIAN: - case MONS_BLACK_DRACONIAN: - case MONS_YELLOW_DRACONIAN: - case MONS_PURPLE_DRACONIAN: - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(120); - mitm[bp].sub_type = ((temp_rand > 109) ? WPN_LONG_SWORD : // 8.33% - (temp_rand > 99) ? WPN_SHORT_SWORD : // 8.33% - (temp_rand > 89) ? WPN_SCIMITAR : // 8.33% - (temp_rand > 79) ? WPN_BATTLEAXE : // 8.33% - (temp_rand > 69) ? WPN_HAND_AXE : // 8.33% - (temp_rand > 59) ? WPN_HALBERD : // 8.33% - (temp_rand > 49) ? WPN_GLAIVE : // 8.33% - (temp_rand > 39) ? WPN_MORNINGSTAR : // 8.33% - (temp_rand > 29) ? WPN_GREAT_MACE : // 8.33% - (temp_rand > 19) ? WPN_TRIDENT : // 8.33% - (temp_rand > 10) ? WPN_WAR_AXE : // 7.50% - (temp_rand > 1) ? WPN_FLAIL : // 7.50% - (temp_rand > 0) ? WPN_BROAD_AXE // 0.83% - : WPN_SPIKED_FLAIL); // 0.83% - break; - - case MONS_ORC_WARLORD: - // being at the top has it's priviledges - if (one_chance_in(3)) - give_level = MAKE_GOOD_ITEM; - // deliberate fall-through - case MONS_ORC_KNIGHT: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall-through, I guess {dlb} - case MONS_NORBERT: - case MONS_JOZEF: - case MONS_URUG: - case MONS_VAULT_GUARD: - case MONS_VAMPIRE_KNIGHT: - case MONS_DRACONIAN_KNIGHT: - mitm[bp].base_type = OBJ_WEAPONS; - - temp_rand = random2(25); - mitm[bp].sub_type = ((temp_rand > 20) ? WPN_GREAT_SWORD : // 16% - (temp_rand > 16) ? WPN_LONG_SWORD : // 16% - (temp_rand > 12) ? WPN_BATTLEAXE : // 16% - (temp_rand > 8) ? WPN_WAR_AXE : // 16% - (temp_rand > 5) ? WPN_GREAT_MACE : // 12% - (temp_rand > 3) ? WPN_DIRE_FLAIL : // 8% - (temp_rand > 2) ? WPN_LOCHABER_AXE : // 4% - (temp_rand > 1) ? WPN_GLAIVE : // 4% - (temp_rand > 0) ? WPN_BROAD_AXE // 4% - : WPN_HALBERD); // 4% - - if (one_chance_in(4)) - mitm[bp].plus += 1 + random2(3); - break; - - case MONS_CYCLOPS: - case MONS_STONE_GIANT: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_MISSILES; - mitm[bp].sub_type = MI_LARGE_ROCK; - break; - - case MONS_TWO_HEADED_OGRE: - case MONS_ETTIN: - item_race = MAKE_ITEM_NO_RACE; - hand_used = 0; - - if (menv[mid].inv[MSLOT_WEAPON] != NON_ITEM) - hand_used = 1; - - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB - : WPN_GIANT_CLUB); - - if (one_chance_in(10) || menv[mid].type == MONS_ETTIN) - { - mitm[bp].sub_type = ((one_chance_in(10)) ? WPN_DIRE_FLAIL - : WPN_GREAT_MACE); - } - break; - - case MONS_REAPER: - give_level = MAKE_GOOD_ITEM; - // intentional fall-through... - - case MONS_SIGMUND: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_SCYTHE; - break; - - case MONS_BALRUG: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_DEMON_WHIP; - break; - - case MONS_RED_DEVIL: - if (!one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = (one_chance_in(3) ? WPN_DEMON_TRIDENT - : WPN_TRIDENT); - } - break; - - case MONS_OGRE: - case MONS_HILL_GIANT: - case MONS_EROLCHA: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - - mitm[bp].sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB - : WPN_GIANT_CLUB); - - if (one_chance_in(10)) - { - mitm[bp].sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL - : WPN_GREAT_MACE); - } - break; - - case MONS_CENTAUR: - case MONS_CENTAUR_WARRIOR: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_BOW; - if (menv[mid].type == MONS_CENTAUR_WARRIOR - && one_chance_in(3)) - mitm[bp].sub_type = WPN_LONGBOW; - break; - - case MONS_YAKTAUR: - case MONS_YAKTAUR_CAPTAIN: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_CROSSBOW; - break; - - case MONS_EFREET: - case MONS_ERICA: - force_item = 1; - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_SCIMITAR; - mitm[bp].plus = random2(5); - mitm[bp].plus2 = random2(5); - mitm[bp].colour = RED; // forced by force_item above {dlb} - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING ); - break; - - case MONS_ANGEL: - force_item = 1; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].colour = WHITE; // forced by force_item above {dlb} - - set_equip_desc( mitm[bp], ISFLAG_GLOWING ); - if (one_chance_in(3)) - { - mitm[bp].sub_type = (one_chance_in(3) ? WPN_GREAT_MACE : WPN_MACE); - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_HOLY_WRATH ); - } - else - { - mitm[bp].sub_type = WPN_LONG_SWORD; - } - - mitm[bp].plus = 1 + random2(3); - mitm[bp].plus2 = 1 + random2(3); - break; - - case MONS_DAEVA: - force_item = 1; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].colour = WHITE; // forced by force_item above {dlb} - - mitm[bp].sub_type = (one_chance_in(4) ? WPN_BLESSED_BLADE - : WPN_LONG_SWORD); - - set_equip_desc( mitm[bp], ISFLAG_GLOWING ); - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_HOLY_WRATH ); - mitm[bp].plus = 1 + random2(3); - mitm[bp].plus2 = 1 + random2(3); - break; - - case MONS_HELL_KNIGHT: - case MONS_MAUD: - case MONS_ADOLF: - case MONS_MARGERY: - force_item = 1; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_LONG_SWORD + random2(3); - - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_HALBERD; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_GLAIVE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_GREAT_MACE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_BATTLEAXE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_WAR_AXE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_BROAD_AXE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_DEMON_TRIDENT; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_DEMON_BLADE; - if (one_chance_in(7)) - mitm[bp].sub_type = WPN_DEMON_WHIP; - - temp_rand = random2(3); - set_equip_desc( mitm[bp], (temp_rand == 1) ? ISFLAG_GLOWING : - (temp_rand == 2) ? ISFLAG_RUNED - : ISFLAG_NO_DESC ); - - if (one_chance_in(3)) - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING ); - else if (one_chance_in(3)) - { - temp_rand = random2(5); - - set_item_ego_type( mitm[bp], OBJ_WEAPONS, - ((temp_rand == 0) ? SPWPN_DRAINING : - (temp_rand == 1) ? SPWPN_VORPAL : - (temp_rand == 2) ? SPWPN_PAIN : - (temp_rand == 3) ? SPWPN_DISTORTION - : SPWPN_SPEED) ); - } - - mitm[bp].plus += random2(6); - mitm[bp].plus2 += random2(6); - - mitm[bp].colour = RED; // forced by force_item above {dlb} - - if (one_chance_in(3)) - mitm[bp].colour = DARKGREY; - if (one_chance_in(5)) - mitm[bp].colour = CYAN; - break; - - case MONS_FIRE_GIANT: - force_item = 1; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_GREAT_SWORD; - mitm[bp].plus = 0; - mitm[bp].plus2 = 0; - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING ); - - mitm[bp].colour = RED; // forced by force_item above {dlb} - if (one_chance_in(3)) - mitm[bp].colour = DARKGREY; - if (one_chance_in(5)) - mitm[bp].colour = CYAN; - break; - - case MONS_FROST_GIANT: - force_item = 1; - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_BATTLEAXE; - mitm[bp].plus = 0; - mitm[bp].plus2 = 0; - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FREEZING ); - - // forced by force_item above {dlb} - mitm[bp].colour = (one_chance_in(3) ? WHITE : CYAN); - break; - - case MONS_KOBOLD_DEMONOLOGIST: - case MONS_ORC_WIZARD: - case MONS_ORC_SORCERER: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall-through, I guess {dlb} - case MONS_NECROMANCER: - case MONS_WIZARD: - case MONS_PSYCHE: - case MONS_DONALD: - case MONS_JOSEPHINE: - case MONS_AGNES: - mitm[bp].base_type = OBJ_WEAPONS; - mitm[bp].sub_type = WPN_DAGGER; - break; - - case MONS_CEREBOV: - force_item = 1; - make_item_fixed_artefact( mitm[bp], false, SPWPN_SWORD_OF_CEREBOV ); - break; - - case MONS_DISPATER: - force_item = 1; - make_item_fixed_artefact( mitm[bp], false, SPWPN_STAFF_OF_DISPATER ); - break; - - case MONS_ASMODEUS: - force_item = 1; - make_item_fixed_artefact( mitm[bp], false, SPWPN_SCEPTRE_OF_ASMODEUS ); - break; - - case MONS_GERYON: - //mv: probably should be moved out of this switch, - //but it's not worth of it, unless we have more - //monsters with misc. items - mitm[bp].base_type = OBJ_MISCELLANY; - mitm[bp].sub_type = MISC_HORN_OF_GERYON; - break; - - case MONS_SALAMANDER: //mv: new 8 Aug 2001 - //Yes, they've got really nice items, but - //it's almost impossible to get them - force_item = 1; - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_WEAPONS; - temp_rand = random2(6); - - mitm[bp].sub_type = ((temp_rand == 5) ? WPN_GREAT_SWORD : - (temp_rand == 4) ? WPN_TRIDENT : - (temp_rand == 3) ? WPN_SPEAR : - (temp_rand == 2) ? WPN_GLAIVE : - (temp_rand == 1) ? WPN_BOW - : WPN_HALBERD); - - if (mitm[bp].sub_type == WPN_BOW) - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAME ); - else - set_item_ego_type( mitm[bp], OBJ_WEAPONS, SPWPN_FLAMING ); - - mitm[bp].plus = random2(5); - mitm[bp].plus2 = random2(5); - mitm[bp].colour = RED; // forced by force_item above {dlb} - break; - } // end "switch(menv[mid].type)" - - // only happens if something in above switch doesn't set it {dlb} - if (mitm[bp].base_type == 101) - { - mitm[bp].base_type = OBJ_UNASSIGNED; - goto give_ammo; - } - - mitm[bp].x = 0; - mitm[bp].y = 0; - mitm[bp].link = NON_ITEM; - - if (force_item) - mitm[bp].quantity = iquan; - else if (mons_is_unique( menv[mid].type )) - { - if (random2(100) <= 9 + menv[mid].hit_dice) - give_level = MAKE_GOOD_ITEM; - else - give_level = level_number + 5; - } - - xitc = mitm[bp].base_type; - xitt = mitm[bp].sub_type; - - // Note this mess, all the work above doesn't mean much unless - // force_item is set... otherwise we're just going to take the - // base and subtypes and create a new item. -- bwr - thing_created = ((force_item) ? bp : items( 0, xitc, xitt, true, - give_level, item_race) ); - - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].x = 0; - mitm[thing_created].y = 0; - mitm[thing_created].link = NON_ITEM; - unset_ident_flags( mitm[thing_created], ISFLAG_IDENT_MASK ); - - //mv: now every item gets in appropriate slot - //no more miscellany in potion slot etc. (19 May 2001) - // hand_used = 0 unless Ettin's 2nd hand etc. - if ( mitm[thing_created].base_type == OBJ_WEAPONS ) - menv[mid].inv[hand_used] = thing_created; - else if ( mitm[thing_created].base_type == OBJ_MISSILES ) - menv[mid].inv[MSLOT_MISSILE] = thing_created; - else if ( mitm[thing_created].base_type == OBJ_SCROLLS ) - menv[mid].inv[MSLOT_SCROLL] = thing_created; - else if ( mitm[thing_created].base_type == OBJ_GOLD ) - menv[mid].inv[MSLOT_GOLD] = thing_created; - else if ( mitm[thing_created].base_type == OBJ_POTIONS ) - menv[mid].inv[MSLOT_POTION] = thing_created; - else if ( mitm[thing_created].base_type == OBJ_MISCELLANY ) - menv[mid].inv[MSLOT_MISCELLANY] = thing_created; - - - if (get_weapon_brand( mitm[thing_created] ) == SPWPN_PROTECTION ) - menv[mid].armour_class += 5; - - if (!force_item || mitm[thing_created].colour == BLACK) - item_colour( mitm[thing_created] ); - - give_ammo: - // mv: gives ammunition - // note that item_race is not reset for this section - if (menv[mid].inv[MSLOT_WEAPON] != NON_ITEM - && launches_things( mitm[menv[mid].inv[MSLOT_WEAPON]].sub_type )) - { - xitc = OBJ_MISSILES; - xitt = launched_by(mitm[menv[mid].inv[MSLOT_WEAPON]].sub_type); - - thing_created = items( 0, xitc, xitt, true, give_level, item_race ); - if (thing_created == NON_ITEM) - return; - - // monsters will always have poisoned needles -- otherwise - // they are just going to behave badly --GDL - if (xitt == MI_NEEDLE) - set_item_ego_type(mitm[thing_created], OBJ_MISSILES, - got_curare_roll(give_level)? - SPMSL_CURARE - : SPMSL_POISONED); - - mitm[thing_created].x = 0; - mitm[thing_created].y = 0; - mitm[thing_created].flags = 0; - menv[mid].inv[MSLOT_MISSILE] = thing_created; - - item_colour( mitm[thing_created] ); - } // end if needs ammo - - bp = get_item_slot(); - if (bp == NON_ITEM) - return; - - mitm[bp].x = 0; - mitm[bp].y = 0; - mitm[bp].link = NON_ITEM; - mitm[bp].orig_place = 0; - mitm[bp].orig_monnum = 0; - - item_race = MAKE_ITEM_RANDOM_RACE; - give_level = 1 + (level_number / 2); - - int force_colour = 0; //mv: important !!! Items with force_colour = 0 - //are colored defaultly after following - //switch. Others will get force_colour. - - switch (menv[mid].type) - { - case MONS_DEEP_ELF_ANNIHILATOR: - case MONS_DEEP_ELF_CONJURER: - case MONS_DEEP_ELF_DEATH_MAGE: - case MONS_DEEP_ELF_DEMONOLOGIST: - case MONS_DEEP_ELF_FIGHTER: - case MONS_DEEP_ELF_HIGH_PRIEST: - case MONS_DEEP_ELF_KNIGHT: - case MONS_DEEP_ELF_MAGE: - case MONS_DEEP_ELF_PRIEST: - case MONS_DEEP_ELF_SOLDIER: - case MONS_DEEP_ELF_SORCERER: - case MONS_DEEP_ELF_SUMMONER: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_ELVEN; - // deliberate fall through {dlb} - case MONS_IJYB: - case MONS_ORC: - case MONS_ORC_HIGH_PRIEST: - case MONS_ORC_PRIEST: - case MONS_ORC_SORCERER: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} - case MONS_ERICA: - case MONS_HAROLD: - case MONS_JOSEPH: - case MONS_JOSEPHINE: - case MONS_JOZEF: - case MONS_NORBERT: - case MONS_PSYCHE: - case MONS_TERENCE: - if (random2(5) < 2) - { - mitm[bp].base_type = OBJ_ARMOUR; - - switch (random2(8)) - { - case 0: - case 1: - case 2: - case 3: - mitm[bp].sub_type = ARM_LEATHER_ARMOUR; - break; - case 4: - case 5: - mitm[bp].sub_type = ARM_RING_MAIL; - break; - case 6: - mitm[bp].sub_type = ARM_SCALE_MAIL; - break; - case 7: - mitm[bp].sub_type = ARM_CHAIN_MAIL; - break; - } - } - else - return; - break; - - case MONS_DUANE: - case MONS_EDMUND: - case MONS_RUPERT: - case MONS_URUG: - case MONS_WAYNE: - mitm[bp].base_type = OBJ_ARMOUR; - mitm[bp].sub_type = ARM_LEATHER_ARMOUR + random2(4); - break; - - case MONS_ORC_WARLORD: - // being at the top has it's priviledges - if (one_chance_in(3)) - give_level = MAKE_GOOD_ITEM; - // deliberate fall through - case MONS_ORC_KNIGHT: - case MONS_ORC_WARRIOR: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} - case MONS_ADOLF: - case MONS_HELL_KNIGHT: - case MONS_LOUISE: - case MONS_MARGERY: - case MONS_MAUD: - case MONS_VAMPIRE_KNIGHT: - case MONS_VAULT_GUARD: - mitm[bp].base_type = OBJ_ARMOUR; - mitm[bp].sub_type = ARM_CHAIN_MAIL + random2(4); - break; - - case MONS_ANGEL: - case MONS_SIGMUND: - case MONS_WIGHT: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_ARMOUR; - mitm[bp].sub_type = ARM_ROBE; - force_colour = WHITE; //mv: always white - break; - - case MONS_NAGA: - case MONS_NAGA_MAGE: - case MONS_NAGA_WARRIOR: - if (!one_chance_in(3)) - return; - // deliberate fall through {dlb} - case MONS_DONALD: - case MONS_GREATER_NAGA: - case MONS_JESSICA: - case MONS_KOBOLD_DEMONOLOGIST: - case MONS_OGRE_MAGE: - case MONS_DRACONIAN: - case MONS_RED_DRACONIAN: - case MONS_WHITE_DRACONIAN: - case MONS_GREEN_DRACONIAN: - case MONS_PALE_DRACONIAN: - case MONS_MOTTLED_DRACONIAN: - case MONS_BLACK_DRACONIAN: - case MONS_YELLOW_DRACONIAN: - case MONS_PURPLE_DRACONIAN: - case MONS_DRACONIAN_SHIFTER: - case MONS_DRACONIAN_SCORCHER: - case MONS_DRACONIAN_ANNIHILATOR: - case MONS_DRACONIAN_CALLER: - case MONS_DRACONIAN_MONK: - case MONS_DRACONIAN_ZEALOT: - case MONS_DRACONIAN_KNIGHT: - case MONS_ORC_WIZARD: - case MONS_WIZARD: - item_race = MAKE_ITEM_NO_RACE; - mitm[bp].base_type = OBJ_ARMOUR; - mitm[bp].sub_type = ARM_ROBE; - break; - - case MONS_BORIS: - give_level = MAKE_GOOD_ITEM; - // fall-through - case MONS_AGNES: - case MONS_BLORK_THE_ORC: - case MONS_FRANCES: - case MONS_FRANCIS: - case MONS_NECROMANCER: - case MONS_VAMPIRE_MAGE: - mitm[bp].base_type = OBJ_ARMOUR; - mitm[bp].sub_type = ARM_ROBE; - force_colour = DARKGREY; //mv: always darkgrey - break; - - default: - return; - } // end of switch(menv [mid].type) - - iquan = 1; //because it may have been set earlier - //by giving ammo or weapons {dlb} - - xitc = mitm[bp].base_type; - xitt = mitm[bp].sub_type; - - if (mons_is_unique( menv[mid].type ) && give_level != MAKE_GOOD_ITEM) - { - if (random2(100) < 9 + menv[mid].hit_dice) - give_level = MAKE_GOOD_ITEM; - else - give_level = level_number + 5; - } - - thing_created = items( 0, xitc, xitt, true, give_level, item_race ); - - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].x = 0; - mitm[thing_created].y = 0; - mitm[thing_created].link = NON_ITEM; - menv[mid].inv[MSLOT_ARMOUR] = thing_created; - - //mv: all items with force_colour = 0 are colored via items(). - if (force_colour) - mitm[thing_created].colour = force_colour; - - menv[mid].armour_class += property( mitm[thing_created], PARM_AC ); - - const int armour_plus = mitm[thing_created].plus; - - ASSERT(abs(armour_plus) < 20); - - if (abs(armour_plus) < 20) - menv[mid].armour_class += armour_plus; - - menv[mid].evasion += property( mitm[thing_created], PARM_EVASION ) / 2; - - if (menv[mid].evasion < 1) - menv[mid].evasion = 1; // This *shouldn't* happen. -} // end give_item() - -//--------------------------------------------------------------------------- -// PRIVATE HELPER FUNCTIONS -//--------------------------------------------------------------------------- - -static bool is_weapon_special(int the_weapon) -{ - return (mitm[the_weapon].special != SPWPN_NORMAL); -} // end is_weapon_special() - -static void set_weapon_special(int the_weapon, int spwpn) -{ - set_item_ego_type( mitm[the_weapon], OBJ_WEAPONS, spwpn ); -} // end set_weapon_special() - -static void check_doors(void) -{ - unsigned char ig; - unsigned char solid_count = 0; // clarifies innermost loop {dlb} - int x,y; - - for (x = 1; x < GXM-1; x++) - { - for (y = 1; y < GYM-1; y++) - { - ig = grd[x][y]; - - if (ig != DNGN_CLOSED_DOOR) - continue; - - solid_count = 0; - - // first half of each conditional represents bounds checking {dlb}: - if (grid_is_solid( grd[x - 1][y] )) - solid_count++; - - if (grid_is_solid( grd[x + 1][y] )) - solid_count++; - - if (grid_is_solid( grd[x][y - 1] )) - solid_count++; - - if (grid_is_solid( grd[x][y + 1] )) - solid_count++; - - grd[x][y] = ((solid_count < 2) ? DNGN_FLOOR : DNGN_CLOSED_DOOR); - } - } -} // end check_doors() - -static void hide_doors(void) -{ - unsigned char dx = 0, dy = 0; // loop variables - unsigned char wall_count = 0; // clarifies inner loop {dlb} - - for (dx = 1; dx < GXM-1; dx++) - { - for (dy = 1; dy < GYM-1; dy++) - { - // only one out of four doors are candidates for hiding {gdl}: - if (grd[dx][dy] == DNGN_CLOSED_DOOR && one_chance_in(4)) - { - wall_count = 0; - - if (grd[dx - 1][dy] == DNGN_ROCK_WALL) - wall_count++; - - if (grd[dx + 1][dy] == DNGN_ROCK_WALL) - wall_count++; - - if (grd[dx][dy - 1] == DNGN_ROCK_WALL) - wall_count++; - - if (grd[dx][dy + 1] == DNGN_ROCK_WALL) - wall_count++; - - // if door is attached to more than one wall, hide it {dlb}: - if (wall_count > 1) - grd[dx][dy] = DNGN_SECRET_DOOR; - } - } - } -} // end hide_doors() - -static void prepare_swamp(void) -{ - int i, j; // loop variables - int temp_rand; // probability determination {dlb} - - for (i = 10; i < (GXM - 10); i++) - { - for (j = 10; j < (GYM - 10); j++) - { - // doors -> floors {dlb} - if (grd[i][j] == DNGN_CLOSED_DOOR || grd[i][j] == DNGN_SECRET_DOOR) - grd[i][j] = DNGN_FLOOR; - - // floors -> shallow water 1 in 3 times {dlb} - if (grd[i][j] == DNGN_FLOOR && one_chance_in(3)) - grd[i][j] = DNGN_SHALLOW_WATER; - - // walls -> deep/shallow water or remain unchanged {dlb} - if (grd[i][j] == DNGN_ROCK_WALL) - { - temp_rand = random2(6); - - if (temp_rand > 0) // 17% chance unchanged {dlb} - { - grd[i][j] = ((temp_rand > 2) ? DNGN_SHALLOW_WATER // 50% - : DNGN_DEEP_WATER); // 33% - } - } - } - } -} // end prepare_swamp() - -// Gives water which is next to ground/shallow water a chance of being -// shallow. Checks each water space. -static void prepare_water( int level_number ) -{ - int i, j, k, l; // loop variables {dlb} - unsigned char which_grid; // code compaction {dlb} - - for (i = 10; i < (GXM - 10); i++) - { - for (j = 10; j < (GYM - 10); j++) - { - if (grd[i][j] == DNGN_DEEP_WATER) - { - for (k = -1; k < 2; k++) - { - for (l = -1; l < 2; l++) - { - if (k != 0 || l != 0) - { - which_grid = grd[i + k][j + l]; - - // must come first {dlb} - if (which_grid == DNGN_SHALLOW_WATER - && one_chance_in( 8 + level_number )) - { - grd[i][j] = DNGN_SHALLOW_WATER; - } - else if (which_grid >= DNGN_FLOOR - && random2(100) < 80 - level_number * 4) - { - grd[i][j] = DNGN_SHALLOW_WATER; - } - } - } - } - } - } - } -} // end prepare_water() - -static bool find_in_area(int sx, int sy, int ex, int ey, unsigned char feature) -{ - int x,y; - - if (feature != 0) - { - for(x = sx; x <= ex; x++) - { - for(y = sy; y <= ey; y++) - { - if (grd[x][y] == feature) - return (true); - } - } - } - - return (false); -} - -// stamp a box. can avoid a possible type, and walls and floors can -// be different (or not stamped at all) -// Note that the box boundaries are INclusive. -static bool make_box(int room_x1, int room_y1, int room_x2, int room_y2, - unsigned char floor, unsigned char wall, unsigned char avoid) -{ - int bx,by; - - // check for avoidance - if (find_in_area(room_x1, room_y1, room_x2, room_y2, avoid)) - return false; - - // draw walls - if (wall != 0) - { - for(bx=room_x1; bx<=room_x2; bx++) - { - grd[bx][room_y1] = wall; - grd[bx][room_y2] = wall; - } - for(by=room_y1+1; by<room_y2; by++) - { - grd[room_x1][by] = wall; - grd[room_x2][by] = wall; - } - } - - // draw floor - if (floor != 0) - { - for(bx=room_x1 + 1; bx < room_x2; bx++) - for(by=room_y1 + 1; by < room_y2; by++) - grd[bx][by] = floor; - } - - return true; -} - -// take care of labyrinth, abyss, pandemonium -// returns 1 if we should skip further generation, -// -1 if we should immediately quit, and 0 otherwise. -static int builder_by_type(int level_number, char level_type) -{ - if (level_type == LEVEL_LABYRINTH) - { - labyrinth_level(level_number); - return -1; - } - - if (level_type == LEVEL_ABYSS) - { - generate_abyss(); - return 1; - } - - if (level_type == LEVEL_PANDEMONIUM) - { - char which_demon = -1; - // Could do spotty_level, but that doesn't always put all paired - // stairs reachable from each other which isn't a problem in normal - // dungeon but could be in Pandemonium - if (one_chance_in(15)) - { - do - { - which_demon = random2(4); - - // makes these things less likely as you find more - if (one_chance_in(4)) - { - which_demon = -1; - break; - } - } - while (you.unique_creatures[40 + which_demon] == 1); - } - - if (which_demon >= 0) - { - you.unique_creatures[40 + which_demon] = 1; - build_vaults(level_number, which_demon + 60); - } - else - { - plan_main(level_number, 0); - build_minivaults(level_number, 300 + random2(9)); - } - - return 1; - } - - // must be normal dungeon - return 0; -} - -// returns 1 if we should skip further generation, -// -1 if we should immediately quit, and 0 otherwise. -static int builder_by_branch(int level_number) -{ - switch (you.where_are_you) - { - case BRANCH_HIVE: - if (level_number == you.branch_stairs[STAIRS_HIVE] - + branch_depth(STAIRS_HIVE)) - build_vaults(level_number, 80); - else - spotty_level(false, 100 + random2(500), false); - return 1; - - case BRANCH_SLIME_PITS: - if (level_number == you.branch_stairs[STAIRS_SLIME_PITS] - + branch_depth(STAIRS_SLIME_PITS)) - { - build_vaults(level_number, 81); - } - else - spotty_level(false, 100 + random2(500), false); - return 1; - - case BRANCH_VAULTS: - if (level_number == you.branch_stairs[STAIRS_VAULTS] - + branch_depth(STAIRS_VAULTS)) - { - build_vaults(level_number, 82); - return 1; - } - break; - - case BRANCH_HALL_OF_BLADES: - if (level_number == you.branch_stairs[STAIRS_HALL_OF_BLADES] - + branch_depth(STAIRS_HALL_OF_BLADES)) - { - build_vaults(level_number, 83); - return 1; - } - break; - - case BRANCH_HALL_OF_ZOT: - if (level_number == you.branch_stairs[STAIRS_HALL_OF_ZOT] - + branch_depth(STAIRS_HALL_OF_ZOT)) - { - build_vaults(level_number, 84); - return 1; - } - break; - - case BRANCH_ECUMENICAL_TEMPLE: - if (level_number == you.branch_stairs[STAIRS_ECUMENICAL_TEMPLE] - + branch_depth(STAIRS_ECUMENICAL_TEMPLE)) - { - build_vaults(level_number, 85); - return 1; - } - break; - - case BRANCH_SNAKE_PIT: - if (level_number == you.branch_stairs[STAIRS_SNAKE_PIT] - + branch_depth(STAIRS_SNAKE_PIT)) - { - build_vaults(level_number, 86); - return 1; - } - break; - - case BRANCH_ELVEN_HALLS: - if (level_number == you.branch_stairs[STAIRS_ELVEN_HALLS] - + branch_depth(STAIRS_ELVEN_HALLS)) - { - build_vaults(level_number, 87); - return 1; - } - break; - - case BRANCH_TOMB: - if (level_number == you.branch_stairs[STAIRS_TOMB] + 1) - { - build_vaults(level_number, 88); - return 1; - } - else if (level_number == you.branch_stairs[STAIRS_TOMB] + 2) - { - build_vaults(level_number, 89); - return 1; - } - else if (level_number == you.branch_stairs[STAIRS_TOMB] + 3) - { - build_vaults(level_number, 90); - return 1; - } - break; - - case BRANCH_SWAMP: - if (level_number == you.branch_stairs[STAIRS_SWAMP] - + branch_depth(STAIRS_SWAMP)) - { - build_vaults(level_number, 91); - return 1; - } - break; - - case BRANCH_ORCISH_MINES: - spotty_level(false, 100 + random2(500), false); - return 1; - - case BRANCH_LAIR: - if (!one_chance_in(3)) - { - spotty_level(false, 100 + random2(500), false); - return 1; - } - break; - - case BRANCH_VESTIBULE_OF_HELL: - build_vaults( level_number, 50 ); - link_items(); - return -1; - - case BRANCH_DIS: - if (level_number == 33) - { - build_vaults(level_number, 51); - return 1; - } - break; - - case BRANCH_GEHENNA: - if (level_number == 33) - { - build_vaults(level_number, 52); - return 1; - } - break; - - case BRANCH_COCYTUS: - if (level_number == 33) - { - build_vaults(level_number, 53); - return 1; - } - break; - - case BRANCH_TARTARUS: - if (level_number == 33) - { - build_vaults(level_number, 54); - return 1; - } - break; - - default: - break; - } - return 0; -} - -// returns 1 if we should dispense with city building, -// 0 otherwise. Also sets special_room if one is generated -// so that we can link it up later. - -static int builder_normal(int level_number, char level_type, spec_room &sr) -{ - UNUSED( level_type ); - - bool skipped = false; - bool done_city = false; - - if (player_in_branch( BRANCH_DIS )) - { - city_level(level_number); - return 1; - } - - if (player_in_branch( BRANCH_MAIN_DUNGEON ) - && level_number > 10 && level_number < 23 && one_chance_in(9)) - { - // Can't have vaults on you.where_are_you != BRANCH_MAIN_DUNGEON levels - build_vaults(level_number, 100); - return 1; - } - - if (player_in_branch( BRANCH_VAULTS )) - { - if (one_chance_in(3)) - city_level(level_number); - else - plan_main(level_number, 4); - return 1; - } - - if (level_number > 7 && level_number < 23) - { - if (one_chance_in(16)) - { - spotty_level(false, 0, coinflip()); - return 1; - } - - if (one_chance_in(16)) - { - bigger_room(); - return 1; - } - } - - if (level_number > 2 && level_number < 23 && one_chance_in(3)) - { - plan_main(level_number, 0); - - if (one_chance_in(3) && level_number > 6) - build_minivaults(level_number, 200); - - return 1; - } - - if (one_chance_in(3)) - skipped = true; - - //V was 3 - if (!skipped && one_chance_in(7)) - { - // sometimes roguey_levels generate a special room - roguey_level(level_number, sr); - - if (level_number > 6 - && player_in_branch( BRANCH_MAIN_DUNGEON ) - && one_chance_in(4)) - { - build_minivaults(level_number, 200); - return 1; - } - } - else - { - if (!skipped && level_number > 13 && one_chance_in(8)) - { - if (one_chance_in(3)) - city_level(level_number); - else - plan_main(level_number, 4); - done_city = true; - } - } - - // maybe create a special room, if roguey_level hasn't done it - // already. - if (!sr.created && level_number > 5 && !done_city && one_chance_in(5)) - special_room(level_number, sr); - - return 0; -} - -// returns 1 if we should skip extras(), otherwise 0 -static int builder_basic(int level_number) -{ - int temp_rand; - int doorlevel = random2(11); - int corrlength = 2 + random2(14); - int roomsize = 4 + random2(5) + random2(6); - int no_corr = (one_chance_in(100) ? 500 + random2(500) : 30 + random2(200)); - int intersect_chance = (one_chance_in(20) ? 400 : random2(20)); - - make_trail( 35, 30, 35, 20, corrlength, intersect_chance, no_corr, - DNGN_STONE_STAIRS_DOWN_I, DNGN_STONE_STAIRS_UP_I ); - - make_trail( 10, 15, 10, 15, corrlength, intersect_chance, no_corr, - DNGN_STONE_STAIRS_DOWN_II, DNGN_STONE_STAIRS_UP_II ); - - make_trail(50,20,10,15,corrlength,intersect_chance,no_corr, - DNGN_STONE_STAIRS_DOWN_III, DNGN_STONE_STAIRS_UP_III); - - if (one_chance_in(4)) - { - make_trail( 10, 20, 40, 20, corrlength, intersect_chance, no_corr, - DNGN_ROCK_STAIRS_DOWN ); - } - - if (one_chance_in(4)) - { - make_trail( 50, 20, 40, 20, corrlength, intersect_chance, no_corr, - DNGN_ROCK_STAIRS_UP ); - } - - - if (level_number > 1 && one_chance_in(16)) - big_room(level_number); - - if (random2(level_number) > 6 && one_chance_in(3)) - diamond_rooms(level_number); - - // make some rooms: - int i, no_rooms, max_doors; - int sx,sy,ex,ey, time_run; - - temp_rand = random2(750); - time_run = 0; - - no_rooms = ((temp_rand > 63) ? (5 + random2avg(29, 2)) : // 91.47% {dlb} - (temp_rand > 14) ? 100 // 6.53% {dlb} - : 1); // 2.00% {dlb} - - max_doors = 2 + random2(8); - - for (i = 0; i < no_rooms; i++) - { - sx = 8 + random2(50); - sy = 8 + random2(40); - ex = sx + 2 + random2(roomsize); - ey = sy + 2 + random2(roomsize); - - if (!make_room(sx,sy,ex,ey,max_doors, doorlevel)) - { - time_run++; - i--; - } - - if (time_run > 30) - { - time_run = 0; - i++; - } - } - - // make some more rooms: - no_rooms = 1 + random2(3); - max_doors = 1; - - for (i = 0; i < no_rooms; i++) - { - sx = 8 + random2(55); - sy = 8 + random2(45); - ex = sx + 5 + random2(6); - ey = sy + 5 + random2(6); - - if (!make_room(sx,sy,ex,ey,max_doors, doorlevel)) - { - time_run++; - i--; - } - - if (time_run > 30) - { - time_run = 0; - i++; - } - } - - return 0; -} - -static void builder_extras( int level_number, int level_type ) -{ - UNUSED( level_type ); - - if (level_number >= 11 && level_number <= 23 && one_chance_in(15)) - place_specific_stair(DNGN_ENTER_LABYRINTH); - - if (level_number > 6 - && player_in_branch( BRANCH_MAIN_DUNGEON ) - && one_chance_in(3)) - { - build_minivaults(level_number, 200); - return; - } - - if (level_number > 5 && one_chance_in(10)) - { - many_pools( (coinflip() ? DNGN_DEEP_WATER : DNGN_LAVA) ); - return; - } - -#ifdef USE_RIVERS - //mv: it's better to be here so other dungeon features - // are not overriden by water - int river_type = one_chance_in( 5 + level_number ) ? DNGN_SHALLOW_WATER - : DNGN_DEEP_WATER; - - if (level_number > 11 - && (one_chance_in(5) || (level_number > 15 && !one_chance_in(5)))) - { - river_type = DNGN_LAVA; - } - - if (player_in_branch( BRANCH_GEHENNA )) - { - river_type = DNGN_LAVA; - - if (coinflip()) - build_river( river_type ); - else - build_lake( river_type ); - } - else if (player_in_branch( BRANCH_COCYTUS )) - { - river_type = DNGN_DEEP_WATER; - - if (coinflip()) - build_river( river_type ); - else - build_lake( river_type ); - } - - - if (level_number > 8 && one_chance_in(16)) - build_river( river_type ); - else if (level_number > 8 && one_chance_in(12)) - { - build_lake( (river_type != DNGN_SHALLOW_WATER) ? river_type - : DNGN_DEEP_WATER ); - } -#endif // USE_RIVERS -} - -static void place_traps(int level_number) -{ - int i; - int num_traps = random2avg(9, 2); - - for (i = 0; i < num_traps; i++) - { - // traps can be placed in vaults - if (env.trap[i].type != TRAP_UNASSIGNED) - continue; - - do - { - env.trap[i].x = 10 + random2(GXM - 20); - env.trap[i].y = 10 + random2(GYM - 20); - } - while (grd[env.trap[i].x][env.trap[i].y] != DNGN_FLOOR); - - unsigned char &trap_type = env.trap[i].type; - trap_type = TRAP_DART; - - if ((random2(1 + level_number) > 1) && one_chance_in(4)) - trap_type = TRAP_NEEDLE; - if (random2(1 + level_number) > 3) - trap_type = TRAP_SPEAR; - if (random2(1 + level_number) > 5) - trap_type = TRAP_AXE; - - // Note we're boosting arrow trap numbers by moving it - // down the list, and making spear and axe traps rarer. - if (trap_type == TRAP_DART? - random2(1 + level_number) > 2 - : one_chance_in(7)) - trap_type = TRAP_ARROW; - - if (random2(1 + level_number) > 7) - trap_type = TRAP_BOLT; - if (random2(1 + level_number) > 11) - trap_type = TRAP_BLADE; - - if ((random2(1 + level_number) > 14 && one_chance_in(3)) - || (player_in_branch( BRANCH_HALL_OF_ZOT ) && coinflip())) - { - trap_type = TRAP_ZOT; - } - - if (one_chance_in(20)) - trap_type = TRAP_TELEPORT; - if (one_chance_in(40)) - trap_type = TRAP_AMNESIA; - - grd[env.trap[i].x][env.trap[i].y] = DNGN_UNDISCOVERED_TRAP; - } // end "for i" -} // end place_traps() - -static void place_specific_stair(unsigned char stair) -{ - int sx, sy; - - do - { - sx = random2(GXM-10); - sy = random2(GYM-10); - } - while(grd[sx][sy] != DNGN_FLOOR || mgrd[sx][sy] != NON_MONSTER); - - grd[sx][sy] = stair; -} - - -static void place_branch_entrances(int dlevel, char level_type) -{ - unsigned char stair; - unsigned char entrance; - int sx, sy; - - if (!level_type == LEVEL_DUNGEON) - return; - - if (player_in_branch( BRANCH_MAIN_DUNGEON )) - { - // stair to HELL - if (dlevel >= 20 && dlevel <= 27) - place_specific_stair(DNGN_ENTER_HELL); - - // stair to PANDEMONIUM - if (dlevel >= 20 && dlevel <= 50 && (dlevel == 23 || one_chance_in(4))) - place_specific_stair(DNGN_ENTER_PANDEMONIUM); - - // stairs to ABYSS - if (dlevel >= 20 && dlevel <= 30 && (dlevel == 24 || one_chance_in(3))) - place_specific_stair(DNGN_ENTER_ABYSS); - - // level 26: replaces all down stairs with staircases to Zot: - if (dlevel == 26) - { - for (sx = 1; sx < GXM; sx++) - { - for (sy = 1; sy < GYM; sy++) - { - if (grd[sx][sy] >= DNGN_STONE_STAIRS_DOWN_I - && grd[sx][sy] <= DNGN_ROCK_STAIRS_DOWN) - { - grd[sx][sy] = DNGN_ENTER_ZOT; - } - } - } - } - } - - // place actual branch entrances - for (int branch = 0; branch < 30; branch++) - { - stair = 0; - entrance = 100; - - if (you.branch_stairs[branch] == 100) // set in newgame - break; - - if (you.branch_stairs[branch] != dlevel) - continue; - - // decide if this branch leaves from this level - switch(branch) - { - case STAIRS_ORCISH_MINES: - case STAIRS_HIVE: - case STAIRS_LAIR: - case STAIRS_VAULTS: - case STAIRS_ECUMENICAL_TEMPLE: - entrance = BRANCH_MAIN_DUNGEON; - break; - - case STAIRS_SLIME_PITS: - case STAIRS_SWAMP: - case STAIRS_SNAKE_PIT: - entrance = BRANCH_LAIR; - break; - - case STAIRS_ELVEN_HALLS: - entrance = BRANCH_ORCISH_MINES; - break; - - case STAIRS_CRYPT: - case STAIRS_HALL_OF_BLADES: - entrance = BRANCH_VAULTS; - break; - - case STAIRS_TOMB: - entrance = BRANCH_CRYPT; - break; - - default: - entrance = 100; - break; - } - - if (you.where_are_you != entrance) - continue; - - stair = branch + DNGN_ENTER_ORCISH_MINES; - place_specific_stair(stair); - } // end loop - possible branch entrances -} - -static void make_trail(int xs, int xr, int ys, int yr, int corrlength, - int intersect_chance, int no_corr, unsigned char begin, - unsigned char end) -{ - int x_start, y_start; // begin point - int x_ps, y_ps; // end point - int finish = 0; - int length = 0; - int temp_rand; - - // temp positions - int dir_x = 0; - int dir_y = 0; - int dir_x2, dir_y2; - - do - { - x_start = xs + random2(xr); - y_start = ys + random2(yr); - } - while (grd[x_start][y_start] != DNGN_ROCK_WALL - && grd[x_start][y_start] != DNGN_FLOOR); - - // assign begin feature - if (begin != 0) - grd[x_start][y_start] = begin; - x_ps = x_start; - y_ps = y_start; - - // wander - do // (while finish < no_corr) - { - dir_x2 = ((x_ps < 15) ? 1 : 0); - - if (x_ps > 65) - dir_x2 = -1; - - dir_y2 = ((y_ps < 15) ? 1 : 0); - - if (y_ps > 55) - dir_y2 = -1; - - temp_rand = random2(10); - - // Put something in to make it go to parts of map it isn't in now - if (coinflip()) - { - if (dir_x2 != 0 && temp_rand < 6) - dir_x = dir_x2; - - if (dir_x2 == 0 || temp_rand >= 6) - dir_x = (coinflip()? -1 : 1); - - dir_y = 0; - } - else - { - if (dir_y2 != 0 && temp_rand < 6) - dir_y = dir_y2; - - if (dir_y2 == 0 || temp_rand >= 6) - dir_y = (coinflip()? -1 : 1); - - dir_x = 0; - } - - if (dir_x == 0 && dir_y == 0) - continue; - - if (x_ps < 8) - { - dir_x = 1; - dir_y = 0; - } - - if (y_ps < 8) - { - dir_y = 1; - dir_x = 0; - } - - if (x_ps > (GXM - 8)) - { - dir_x = -1; - dir_y = 0; - } - - if (y_ps > (GYM - 8)) - { - dir_y = -1; - dir_x = 0; - } - - // corridor length.. change only when going vertical? - if (dir_x == 0 || length == 0) - length = random2(corrlength) + 2; - - int bi = 0; - - for (bi = 0; bi < length; bi++) - { - // Below, I've changed the values of the unimportant variable from - // 0 to random2(3) - 1 to avoid getting stuck on the "stuck!" bit - if (x_ps < 9) - { - dir_y = 0; //random2(3) - 1; - dir_x = 1; - } - - if (x_ps > (GXM - 9)) - { - dir_y = 0; //random2(3) - 1; - dir_x = -1; - } - - if (y_ps < 9) - { - dir_y = 1; - dir_x = 0; //random2(3) - 1; - } - - if (y_ps > (GYM - 9)) - { - dir_y = -1; - dir_x = 0; //random2(3) - 1; - } - - // don't interfere with special rooms - if (grd[x_ps + dir_x][y_ps + dir_y] == DNGN_BUILDER_SPECIAL_WALL) - break; - - // see if we stop due to intersection with another corridor/room - if (grd[x_ps + 2 * dir_x][y_ps + 2 * dir_y] == DNGN_FLOOR - && !one_chance_in(intersect_chance)) - break; - - x_ps += dir_x; - y_ps += dir_y; - - if (grd[x_ps][y_ps] == DNGN_ROCK_WALL) - grd[x_ps][y_ps] = DNGN_FLOOR; - } - - if (finish == no_corr - 1 && grd[x_ps][y_ps] != DNGN_FLOOR) - finish -= 2; - - finish++; - } - while (finish < no_corr); - - // assign end feature - if (end != 0) - grd[x_ps][y_ps] = end; -} - -static int good_door_spot(int x, int y) -{ - if ((!grid_is_solid(grd[x][y]) && grd[x][y] < DNGN_ENTER_PANDEMONIUM) - || grd[x][y] == DNGN_CLOSED_DOOR) - { - return 1; - } - - return 0; -} - -// return TRUE if a room was made successfully -static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel) -{ - int find_door = 0; - int diag_door = 0; - int rx,ry; - - // check top & bottom for possible doors - for (rx = sx; rx <= ex; rx++) - { - find_door += good_door_spot(rx,sy); - find_door += good_door_spot(rx,ey); - } - - // check left and right for possible doors - for (ry = sy+1; ry < ey; ry++) - { - find_door += good_door_spot(sx,ry); - find_door += good_door_spot(ex,ry); - } - - diag_door += good_door_spot(sx,sy); - diag_door += good_door_spot(ex,sy); - diag_door += good_door_spot(sx,ey); - diag_door += good_door_spot(ex,ey); - - if ((diag_door + find_door) > 1 && max_doors == 1) - return false; - - if (find_door == 0 || find_door > max_doors) - return false; - - // look for 'special' rock walls - don't interrupt them - if (find_in_area(sx,sy,ex,ey,DNGN_BUILDER_SPECIAL_WALL)) - return false; - - // convert the area to floor - for (rx=sx; rx<=ex; rx++) - { - for(ry=sy; ry<=ey; ry++) - { - if (grd[rx][ry] <= DNGN_FLOOR) - grd[rx][ry] = DNGN_FLOOR; - } - } - - // put some doors on the sides (but not in corners), - // where it makes sense to do so. - for(ry=sy+1; ry<ey; ry++) - { - // left side - if (grd[sx-1][ry] == DNGN_FLOOR - && grid_is_solid(grd[sx-1][ry-1]) - && grid_is_solid(grd[sx-1][ry+1])) - { - if (random2(10) < doorlevel) - grd[sx-1][ry] = DNGN_CLOSED_DOOR; - } - - // right side - if (grd[ex+1][ry] == DNGN_FLOOR - && grid_is_solid(grd[ex+1][ry-1]) - && grid_is_solid(grd[ex+1][ry+1])) - { - if (random2(10) < doorlevel) - grd[ex+1][ry] = DNGN_CLOSED_DOOR; - } - } - - // put some doors on the top & bottom - for(rx=sx+1; rx<ex; rx++) - { - // top - if (grd[rx][sy-1] == DNGN_FLOOR - && grid_is_solid(grd[rx-1][sy-1]) - && grid_is_solid(grd[rx+1][sy-1])) - { - if (random2(10) < doorlevel) - grd[rx][sy-1] = DNGN_CLOSED_DOOR; - } - - // bottom - if (grd[rx][ey+1] == DNGN_FLOOR - && grid_is_solid(grd[rx-1][ey+1]) - && grid_is_solid(grd[rx+1][ey+1])) - { - if (random2(10) < doorlevel) - grd[rx][ey+1] = DNGN_CLOSED_DOOR; - } - } - - return true; -} //end make_room() - -static void builder_monsters(int level_number, char level_type, int mon_wanted) -{ - int i = 0; - int totalplaced = 0; - int not_used=0; - int x,y; - int lava_spaces, water_spaces; - int aq_creatures; - int swimming_things[4]; - - if (level_type == LEVEL_PANDEMONIUM) - return; - - for (i = 0; i < mon_wanted; i++) - { - if (place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP, - MHITNOT, false, 1, 1, true )) - { - totalplaced++; - } - } - - // Unique beasties: - int which_unique; - - if (level_number > 0 - && you.level_type == LEVEL_DUNGEON // avoid generating on temp levels - && !player_in_hell() - && !player_in_branch( BRANCH_ORCISH_MINES ) - && !player_in_branch( BRANCH_HIVE ) - && !player_in_branch( BRANCH_LAIR ) - && !player_in_branch( BRANCH_SLIME_PITS ) - && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) - { - while(one_chance_in(3)) - { - which_unique = -1; // 30 in total - - while(which_unique < 0 || you.unique_creatures[which_unique]) - { - // sometimes, we just quit if a unique is already placed. - if (which_unique >= 0 && !one_chance_in(3)) - { - which_unique = -1; - break; - } - - which_unique = ((level_number > 19) ? 20 + random2(11) : - (level_number > 16) ? 13 + random2(10) : - (level_number > 13) ? 9 + random2( 9) : - (level_number > 9) ? 6 + random2( 5) : - (level_number > 7) ? 4 + random2( 4) : - (level_number > 3) ? 2 + random2( 4) - : random2(4)); - } - - // usually, we'll have quit after a few tries. Make sure we don't - // create unique[-1] by accident. - if (which_unique < 0) - break; - - // note: unique_creatures 40 + used by unique demons - if (place_monster( not_used, 280 + which_unique, level_number, - BEH_SLEEP, MHITNOT, false, 1, 1, true )) - { - totalplaced++; - } - } - } - - // do aquatic and lava monsters: - - // count the number of lava and water tiles {dlb}: - lava_spaces = 0; - water_spaces = 0; - - for (x = 0; x < GXM; x++) - { - for (y = 0; y < GYM; y++) - { - if (grd[x][y] == DNGN_LAVA) - { - lava_spaces++; - } - else if (grd[x][y] == DNGN_DEEP_WATER - || grd[x][y] == DNGN_SHALLOW_WATER) - { - water_spaces++; - } - } - } - - if (lava_spaces > 49) - { - for (i = 0; i < 4; i++) - { - swimming_things[i] = MONS_LAVA_WORM + random2(3); - - //mv: this is really ugly, but easiest - //IMO generation of water/lava beasts should be changed, - //because we want data driven code and not things like it - if (one_chance_in(30)) - swimming_things[i] = MONS_SALAMANDER; - } - - aq_creatures = random2avg(9, 2) + (random2(lava_spaces) / 10); - - if (aq_creatures > 15) - aq_creatures = 15; - - for (i = 0; i < aq_creatures; i++) - { - if (place_monster( not_used, swimming_things[ random2(4) ], - level_number, BEH_SLEEP, MHITNOT, - false, 1, 1, true )) - { - totalplaced++; - } - - if (totalplaced > 99) - break; - } - } - - if (water_spaces > 49) - { - for (i = 0; i < 4; i++) - { - // mixing enums and math ticks me off !!! 15jan2000 {dlb} - swimming_things[i] = MONS_BIG_FISH + random2(4); - - // swamp worms and h2o elementals generated below: {dlb} - if (player_in_branch( BRANCH_SWAMP ) && !one_chance_in(3)) - swimming_things[i] = MONS_SWAMP_WORM; - } - - if (level_number >= 25 && one_chance_in(5)) - swimming_things[0] = MONS_WATER_ELEMENTAL; - - if (player_in_branch( BRANCH_COCYTUS )) - swimming_things[3] = MONS_WATER_ELEMENTAL; - - aq_creatures = random2avg(9, 2) + (random2(water_spaces) / 10); - - if (aq_creatures > 15) - aq_creatures = 15; - - for (i = 0; i < aq_creatures; i++) - { - if (place_monster( not_used, swimming_things[ random2(4) ], - level_number, BEH_SLEEP, MHITNOT, - false, 1, 1, true )) - { - totalplaced++; - } - - if (totalplaced > 99) - break; - } - } -} - -static void builder_items(int level_number, char level_type, int items_wanted) -{ - UNUSED( level_type ); - - int i = 0; - unsigned char specif_type = OBJ_RANDOM; - int items_levels = level_number; - int item_no; - - if (player_in_branch( BRANCH_VAULTS )) - { - items_levels *= 15; - items_levels /= 10; - } - else if (player_in_branch( BRANCH_ORCISH_MINES )) - { - specif_type = OBJ_GOLD; /* lots of gold in the orcish mines */ - } - - if (player_in_branch( BRANCH_VESTIBULE_OF_HELL ) - || player_in_hell() - || player_in_branch( BRANCH_SLIME_PITS ) - || player_in_branch( BRANCH_HALL_OF_BLADES ) - || player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) - { - /* No items in hell, the slime pits, the Hall */ - return; - } - else - { - for (i = 0; i < items_wanted; i++) - items( 1, specif_type, OBJ_RANDOM, false, items_levels, 250 ); - - // Make sure there's a very good chance of a knife being placed - // in the first five levels, but not a guarantee of one. The - // intent of this is to reduce the advantage that "cutting" - // starting weapons have. -- bwr - if (player_in_branch( BRANCH_MAIN_DUNGEON ) - && level_number < 5 && coinflip()) - { - item_no = items( 0, OBJ_WEAPONS, WPN_KNIFE, false, 0, 250 ); - - // Guarantee that the knife is uncursed and non-special - if (item_no != NON_ITEM) - { - mitm[item_no].plus = 0; - mitm[item_no].plus2 = 0; - mitm[item_no].flags = 0; // no id, no race/desc, no curse - mitm[item_no].special = 0; // no ego type - } - } - } -} - -// the entire intent of this function is to find a -// hallway from a special room to a floor space somewhere, -// changing the special room wall (DNGN_BUILDER_SPECIAL_WALL) -// to a closed door, and normal rock wall to pre-floor. -// Anything that might otherwise block the hallway is changed -// to pre-floor. -static void specr_2(spec_room &sr) -{ - int bkout = 0; - int cx = 0, cy = 0; - int sx = 0, sy = 0; - int dx = 0, dy = 0; - int i,j; - - // paranoia -- how did we get here if there's no actual special room?? - if (!sr.created) - return; - - grolko: - - if (bkout > 100) - return; - - switch (random2(4)) - { - case 0: - // go up from north edge - cx = sr.x1 + (random2(sr.x2 - sr.x1)); - cy = sr.y1; - dx = 0; - dy = -1; - break; - case 1: - // go down from south edge - cx = sr.x1 + (random2(sr.x2 - sr.x1)); - cy = sr.y2; - dx = 0; - dy = 1; - break; - case 2: - // go left from west edge - cy = sr.y1 + (random2(sr.y2 - sr.y1)); - cx = sr.x1; - dx = -1; - dy = 0; - break; - case 3: - // go right from east edge - cy = sr.y1 + (random2(sr.y2 - sr.y1)); - cx = sr.x2; - dx = 1; - dy = 0; - break; - } - - sx = cx; - sy = cy; - - for (i = 0; i < 100; i++) - { - sx += dx; - sy += dy; - - // quit if we run off the map before finding floor - if (sx < 6 || sx > (GXM - 7) || sy < 6 || sy > (GYM - 7)) - { - bkout++; - goto grolko; - } - - // look around for floor - if (i > 0) - { - if (grd[sx + 1][sy] == DNGN_FLOOR) - break; - if (grd[sx][sy + 1] == DNGN_FLOOR) - break; - if (grd[sx - 1][sy] == DNGN_FLOOR) - break; - if (grd[sx][sy - 1] == DNGN_FLOOR) - break; - } - } - - sx = cx; - sy = cy; - - for (j = 0; j < i + 2; j++) - { - if (grd[sx][sy] == DNGN_BUILDER_SPECIAL_WALL) - grd[sx][sy] = DNGN_CLOSED_DOOR; - - if (j > 0 && grd[sx + dx][sy + dy] > DNGN_ROCK_WALL - && grd[sx + dx][sy + dy] < DNGN_FLOOR) - grd[sx][sy] = DNGN_BUILDER_SPECIAL_FLOOR; - - if (grd[sx][sy] == DNGN_ROCK_WALL) - grd[sx][sy] = DNGN_BUILDER_SPECIAL_FLOOR; - - sx += dx; - sy += dy; - } - - sr.hooked_up = true; -} // end specr_2() - -// Fill special room sr with monsters from the pit_list at density%... -// then place a "lord of the pit" of lord_type at (lordx, lordy). -static void fill_monster_pit( spec_room &sr, - FixedVector<pit_mons_def, MAX_PIT_MONSTERS> &pit_list, - int density, int lord_type, int lordx, int lordy ) -{ - int i, x, y; - - // make distribution cumulative - for (i = 1; i < MAX_PIT_MONSTERS; i++) - { - // assuming that the first zero rarity is the end of the list: - if (!pit_list[i].rare) - break; - - pit_list[i].rare = pit_list[i].rare + pit_list[i - 1].rare; - } - - const int num_types = i; - const int rare_sum = pit_list[num_types - 1].rare; - - // calculate die_size, factoring in the density% of the pit - const int die_size = (rare_sum * 100) / density; - -#if DEBUG_DIAGNOSTICS - for (i = 0; i < num_types; i++) - { - char buff[ ITEMNAME_SIZE ]; - - const int delta = ((i > 0) ? pit_list[i].rare - pit_list[i - 1].rare - : pit_list[i].rare); - - const float perc = (static_cast<float>( delta ) * 100.0) - / static_cast<float>( rare_sum ); - - mprf( MSGCH_DIAGNOSTICS, "%6.2f%%: %s", perc, - moname( pit_list[i].type, true, DESC_PLAIN, buff ) ); - } -#endif - - // put the boss monster down - if (lord_type != MONS_PROGRAM_BUG) - mons_place( lord_type, BEH_SLEEP, MHITNOT, true, lordx, lordy ); - - // place monsters and give them items {dlb}: - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - // avoid the boss (or anyone else we may have dropped already) - if (mgrd[x][y] != NON_MONSTER) - continue; - - const int roll = random2( die_size ); - - // density skip (no need to iterate) - if (roll >= rare_sum) - continue; - - // run throught the cumulative chances and place a monster - for (i = 0; i < num_types; i++) - { - if (roll < pit_list[i].rare) - { - mons_place( pit_list[i].type, BEH_SLEEP, MHITNOT, - true, x, y ); - break; - } - } - } - } -} - -static void special_room(int level_number, spec_room &sr) -{ - char spec_room_type = SROOM_LAIR_KOBOLD; - int lev_mons; - int thing_created = 0; - int x, y; - - unsigned char obj_type = OBJ_RANDOM; // used in calling items() {dlb} - unsigned char i; // general purpose loop variable {dlb} - int temp_rand = 0; // probability determination {dlb} - - FixedVector < int, 10 > mons_alloc; // was [20] {dlb} - - char lordx = 0, lordy = 0; - - // overwrites anything; this function better be called early on during - // creation.. - int room_x1 = 8 + random2(55); - int room_y1 = 8 + random2(45); - int room_x2 = room_x1 + 4 + random2avg(6,2); - int room_y2 = room_y1 + 4 + random2avg(6,2); - - // do special walls & floor - make_box( room_x1, room_y1, room_x2, room_y2, - DNGN_BUILDER_SPECIAL_FLOOR, DNGN_BUILDER_SPECIAL_WALL ); - - // set up passed in spec_room structure - sr.created = true; - sr.hooked_up = false; - sr.x1 = room_x1 + 1; - sr.x2 = room_x2 - 1; - sr.y1 = room_y1 + 1; - sr.y2 = room_y2 - 1; - - if (level_number < 7) - spec_room_type = SROOM_LAIR_KOBOLD; - else - { - spec_room_type = random2(NUM_SPECIAL_ROOMS); - - if (level_number < 23 && one_chance_in(4)) - spec_room_type = SROOM_BEEHIVE; - - if ((level_number > 13 && spec_room_type == SROOM_LAIR_KOBOLD) - || (level_number < 16 && spec_room_type == SROOM_MORGUE) - || (level_number < 17 && one_chance_in(4))) - { - spec_room_type = SROOM_LAIR_ORC; - } - - if (level_number > 19 && coinflip()) - spec_room_type = SROOM_MORGUE; - - if (level_number > 13 - && one_chance_in(level_number > 23? 4 : - level_number > 18? 5 : 6)) - spec_room_type = SROOM_JELLY_PIT; - } - - switch (spec_room_type) - { - case SROOM_LAIR_ORC: - // determine which monster array to generate {dlb}: - lev_mons = ((level_number > 24) ? 3 : - (level_number > 15) ? 2 : - (level_number > 9) ? 1 - : 0); - - // fill with baseline monster type {dlb}: - for (i = 0; i < 10; i++) - { - mons_alloc[i] = MONS_ORC; - } - - // fill in with special monster types {dlb}: - switch (lev_mons) - { - case 0: - mons_alloc[9] = MONS_ORC_WARRIOR; - break; - case 1: - mons_alloc[8] = MONS_ORC_WARRIOR; - mons_alloc[9] = MONS_ORC_WARRIOR; - break; - case 2: - mons_alloc[6] = MONS_ORC_KNIGHT; - mons_alloc[7] = MONS_ORC_WARRIOR; - mons_alloc[8] = MONS_ORC_WARRIOR; - mons_alloc[9] = MONS_OGRE; - break; - case 3: - mons_alloc[2] = MONS_ORC_WARRIOR; - mons_alloc[3] = MONS_ORC_WARRIOR; - mons_alloc[4] = MONS_ORC_WARRIOR; - mons_alloc[5] = MONS_ORC_KNIGHT; - mons_alloc[6] = MONS_ORC_KNIGHT; - mons_alloc[7] = MONS_OGRE; - mons_alloc[8] = MONS_OGRE; - mons_alloc[9] = MONS_TROLL; - break; - } - - // place monsters and give them items {dlb}: - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - if (one_chance_in(4)) - continue; - - mons_place( mons_alloc[random2(10)], BEH_SLEEP, MHITNOT, - true, x, y ); - } - } - break; - - case SROOM_LAIR_KOBOLD: - lordx = sr.x1 + random2(sr.x2 - sr.x1); - lordy = sr.y1 + random2(sr.y2 - sr.y1); - - // determine which monster array to generate {dlb}: - lev_mons = ((level_number < 4) ? 0 : - (level_number < 6) ? 1 : (level_number < 9) ? 2 : 3); - - // fill with baseline monster type {dlb}: - for (i = 0; i < 10; i++) - { - mons_alloc[i] = MONS_KOBOLD; - } - - // fill in with special monster types {dlb}: - // in this case, they are uniformly the same {dlb}: - for (i = (7 - lev_mons); i < 10; i++) - { - mons_alloc[i] = MONS_BIG_KOBOLD; - } - - // place monsters and give them items {dlb}: - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - if (one_chance_in(4)) - continue; - - // we'll put the boss down later. - if (x == lordx && y == lordy) - continue; - - mons_place( mons_alloc[random2(10)], BEH_SLEEP, MHITNOT, - true, x, y ); - } - } - - // put the boss monster down - mons_place( MONS_BIG_KOBOLD, BEH_SLEEP, MHITNOT, true, lordx, lordy ); - - break; - - case SROOM_TREASURY: - // should only appear in deep levels, with a guardian - // Maybe have several types of treasure room? - // place treasure {dlb}: - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - temp_rand = random2(11); - - obj_type = ((temp_rand > 8) ? OBJ_WEAPONS : // 2 in 11 - (temp_rand > 6) ? OBJ_ARMOUR : // 2 in 11 - (temp_rand > 5) ? OBJ_MISSILES : // 1 in 11 - (temp_rand > 4) ? OBJ_WANDS : // 1 in 11 - (temp_rand > 3) ? OBJ_SCROLLS : // 1 in 11 - (temp_rand > 2) ? OBJ_JEWELLERY : // 1 in 11 - (temp_rand > 1) ? OBJ_BOOKS : // 1 in 11 - (temp_rand > 0) ? OBJ_STAVES // 1 in 11 - : OBJ_POTIONS); // 1 in 11 - - thing_created = items( 1, obj_type, OBJ_RANDOM, true, - level_number * 3, 250 ); - - if (thing_created != NON_ITEM) - { - mitm[thing_created].x = x; - mitm[thing_created].y = y; - } - } - } - - // place guardian {dlb}: - mons_place( MONS_GUARDIAN_NAGA, BEH_SLEEP, MHITNOT, true, - sr.x1 + random2( sr.x2 - sr.x1 ), - sr.y1 + random2( sr.y2 - sr.y1 ) ); - - break; - - case SROOM_BEEHIVE: - beehive(sr); - break; - - case SROOM_MORGUE: - morgue(sr); - break; - - case SROOM_JELLY_PIT: - jelly_pit(level_number, sr); - break; - } -} // end special_room() - -// fills a special room with bees -static void beehive(spec_room &sr) -{ - int i; - int x,y; - - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - if (coinflip()) - continue; - - i = get_item_slot(); - if (i == NON_ITEM) - goto finished_food; - - mitm[i].quantity = 1; - mitm[i].base_type = OBJ_FOOD; - mitm[i].sub_type = (one_chance_in(25) ? FOOD_ROYAL_JELLY - : FOOD_HONEYCOMB); - mitm[i].x = x; - mitm[i].y = y; - - item_colour( mitm[i] ); - } - } - - - finished_food: - - int queenx = sr.x1 + random2(sr.x2 - sr.x1); - int queeny = sr.y1 + random2(sr.y2 - sr.y1); - - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - if (x == queenx && y == queeny) - continue; - - // the hive is chock full of bees! - - mons_place( one_chance_in(7) ? MONS_KILLER_BEE_LARVA - : MONS_KILLER_BEE, - BEH_SLEEP, MHITNOT, true, x, y ); - } - } - - mons_place( MONS_QUEEN_BEE, BEH_SLEEP, MHITNOT, true, queenx, queeny ); -} // end beehive() - -static void build_minivaults(int level_number, int force_vault) -{ - // for some weird reason can't put a vault on level 1, because monster equip - // isn't generated. - int altar_count = 0; - - FixedVector < char, 7 > acq_item_class; - // hack - passing chars through '...' promotes them to ints, which - // barfs under gcc in fixvec.h. So don't. - acq_item_class[0] = OBJ_WEAPONS; - acq_item_class[1] = OBJ_ARMOUR; - acq_item_class[2] = OBJ_WEAPONS; - acq_item_class[3] = OBJ_JEWELLERY; - acq_item_class[4] = OBJ_BOOKS; - acq_item_class[5] = OBJ_STAVES; - acq_item_class[6] = OBJ_MISCELLANY; - - FixedVector < int, 7 > mons_array(RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER); - - char vgrid[81][81]; - - if (force_vault == 200) - { - force_vault = 200 + random2(37); - } - - vault_main(vgrid, mons_array, force_vault, level_number); - - int vx, vy; - int v1x, v1y; - - /* find a target area which can be safely overwritten: */ - while(1) - { - //if ( one_chance_in(1000) ) return; - v1x = 12 + random2(45); - v1y = 12 + random2(35); - - for (vx = v1x; vx < v1x + 12; vx++) - { - for (vy = v1y; vy < v1y + 12; vy++) - { - if (one_chance_in(2000)) - return; - - if ((grd[vx][vy] != DNGN_FLOOR - && grd[vx][vy] != DNGN_ROCK_WALL - && grd[vx][vy] != DNGN_CLOSED_DOOR - && grd[vx][vy] != DNGN_SECRET_DOOR) - || igrd[vx][vy] != NON_ITEM - || mgrd[vx][vy] != NON_MONSTER) - { - goto out_of_check; - } - } - } - - /* must not be completely isolated: */ - for (vx = v1x; vx < v1x + 12; vx++) - { - // if (vx != v1x && vx != v1x + 12) continue; - for (vy = v1y; vy < v1y + 12; vy++) - { - // if (vy != v1y && vy != v1y + 12) continue; - if (grd[vx][vy] == DNGN_FLOOR - || grd[vx][vy] == DNGN_CLOSED_DOOR - || grd[vx][vy] == DNGN_SECRET_DOOR) - goto break_out; - } - } - - out_of_check: - continue; - - break_out: - break; - } - - for (vx = v1x; vx < v1x + 12; vx++) - { - for (vy = v1y; vy < v1y + 12; vy++) - { - grd[vx][vy] = vgrid[vx - v1x][vy - v1y]; - } - } - - // these two are throwaways: - int initial_x, initial_y; - int num_runes = 0; - - // paint the minivault onto the grid - for (vx = v1x; vx < v1x + 12; vx++) - { - for (vy = v1y; vy < v1y + 12; vy++) - { - altar_count = vault_grid( level_number, vx, vy, altar_count, - acq_item_class, mons_array, - grd[vx][vy], initial_x, initial_y, - force_vault, num_runes ); - } - } -} // end build_minivaults() - -static void build_vaults(int level_number, int force_vault) -{ - // for some weird reason can't put a vault on level 1, because monster equip - // isn't generated. - int i,j; // general loop variables - int altar_count = 0; - FixedVector < char, 10 > stair_exist; - char stx, sty; - int initial_x=0, initial_y=0; - - FixedVector < char, 7 > acq_item_class; - // hack - passing chars through '...' promotes them to ints, which - // barfs under gcc in fixvec.h. So don't. -- GDL - acq_item_class[0] = OBJ_WEAPONS; - acq_item_class[1] = OBJ_ARMOUR; - acq_item_class[2] = OBJ_WEAPONS; - acq_item_class[3] = OBJ_JEWELLERY; - acq_item_class[4] = OBJ_BOOKS; - acq_item_class[5] = OBJ_STAVES; - acq_item_class[6] = OBJ_MISCELLANY; - - FixedVector < int, 7 > mons_array(RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER, - RANDOM_MONSTER); - - int roomsss = 10 + random2(90); - int which_room = 0; - - bool exclusive = (one_chance_in(10) ? false : true); - - //bool exclusive2 = coinflip(); // usage commented out below {dlb} - - char vgrid[81][81]; - - char gluggy = vault_main(vgrid, mons_array, force_vault, level_number); - - int vx, vy; - int v1x = 0, v1y = 0, v2x = 0, v2y = 0; - - //int item_made; - - char dig_dir_x = 0; - char dig_dir_y = 0; - char dig_place_x = 0; - char dig_place_y = 0; - int num_runes = 0; - - // note: assumes *no* previous item (I think) or monster (definitely) - // placement - for (vx = 0; vx < GXM; vx++) - { - for (vy = 0; vy < GYM; vy++) - { - altar_count = vault_grid( level_number, vx, vy, altar_count, - acq_item_class, mons_array, - vgrid[vy][vx], initial_x, initial_y, - force_vault, num_runes ); - } - } - - switch (gluggy) - { - case MAP_NORTH: - v1x = 1; - v2x = GXM; - v1y = 1; - v2y = 35; - initial_y++; - dig_dir_x = 0; - dig_dir_y = 1; - break; - - case MAP_NORTHWEST: - v1x = 1; - v2x = 40; - v1y = 1; - v2y = 35; - initial_y++; - dig_dir_x = 1; - dig_dir_y = 0; - break; - - case MAP_NORTHEAST: - v1x = 40; - v2x = GXM; - v1y = 1; - v2y = 35; - initial_y++; - dig_dir_x = -1; - dig_dir_y = 0; - break; - - case MAP_SOUTHWEST: - v1x = 1; - v2x = 40; - v1y = 35; - v2y = GYM; - initial_y--; - dig_dir_x = 0; - dig_dir_y = -1; - break; - - case MAP_SOUTHEAST: - v1x = 40; - v2x = GXM; - v1y = 35; - v2y = GYM; - initial_y--; - dig_dir_x = 0; - dig_dir_y = -1; - break; - - case MAP_ENCOMPASS: - return; - - case MAP_NORTH_DIS: - v1x = 1; - v2x = GXM; - v1y = 1; - v2y = 35; - plan_4(1, 1, 80, 35, DNGN_METAL_WALL); - goto vstair; - } - - char cnx, cny; - char romx1[30], romy1[30], romx2[30], romy2[30]; - - for (i = 0; i < roomsss; i++) - { - do - { - romx1[which_room] = 10 + random2(50); - romy1[which_room] = 10 + random2(40); - romx2[which_room] = romx1[which_room] + 2 + random2(8); - romy2[which_room] = romy1[which_room] + 2 + random2(8); - } - while ((romx1[which_room] >= v1x && romx1[which_room] <= v2x - && romy1[which_room] >= v1y && romy1[which_room] <= v2y) - || (romx2[which_room] >= v1x && romx2[which_room] <= v2x - && romy2[which_room] >= v1y && romy2[which_room] <= v2y)); - - if (i == 0) - { - join_the_dots(initial_x, initial_y, romx1[which_room], romy1[which_room], - v1x, v1y, v2x, v2y); - } - else if (exclusive) - { - for (cnx = romx1[which_room] - 1; cnx < romx2[which_room] + 1; - cnx++) - { - for (cny = romy1[which_room] - 1; cny < romy2[which_room] + 1; - cny++) - { - if (grd[cnx][cny] != DNGN_ROCK_WALL) - goto continuing; - } - } - } - - replace_area(romx1[which_room], romy1[which_room], romx2[which_room], - romy2[which_room], DNGN_ROCK_WALL, DNGN_FLOOR); - - if (which_room > 0) // && !exclusive2 - { - const int rx1 = romx1[which_room]; - const int rx2 = romx2[which_room]; - const int prev_rx1 = romx1[which_room - 1]; - const int prev_rx2 = romx2[which_room - 1]; - - const int ry1 = romy1[which_room]; - const int ry2 = romy2[which_room]; - const int prev_ry1 = romy1[which_room - 1]; - const int prev_ry2 = romy2[which_room - 1]; - - join_the_dots( rx1 + random2( rx2 - rx1 ), - ry1 + random2( ry2 - ry1 ), - prev_rx1 + random2( prev_rx2 - prev_rx1 ), - prev_ry1 + random2( prev_ry2 - prev_ry1 ), - v1x, v1y, v2x, v2y); - } - - which_room++; - - if (which_room >= 29) - break; - - continuing: - continue; // next i loop - - } - - vstair: - dig_place_x = initial_x; - dig_place_y = initial_y; - - if (gluggy != MAP_NORTH_DIS) - { - for (i = 0; i < 40; i++) - { - dig_place_x += dig_dir_x; - dig_place_y += dig_dir_y; - - if (dig_place_x < 10 || dig_place_x > (GXM - 10) - || dig_place_y < 10 || dig_place_y > (GYM - 10)) - { - break; - } - - if (grd[dig_place_x][dig_place_y] == DNGN_ROCK_WALL) - grd[dig_place_x][dig_place_y] = DNGN_FLOOR; - } - } - - unsigned char pos_x, pos_y; - - for (stx = 0; stx < 10; stx++) - stair_exist[stx] = 0; - - for (stx = 0; stx < GXM; stx++) - { - for (sty = 0; sty < GYM; sty++) - { - if (grd[stx][sty] >= DNGN_STONE_STAIRS_DOWN_I - && grd[stx][sty] <= DNGN_ROCK_STAIRS_UP) - { - stair_exist[grd[stx][sty] - 82] = 1; - } - } - } - - if (player_in_branch( BRANCH_DIS )) - { - for (sty = 0; sty < 5; sty++) - stair_exist[sty] = 1; - - for (sty = 6; sty < 10; sty++) - stair_exist[sty] = 0; - } - - for (j = 0; j < (coinflip()? 4 : 3); j++) - { - for (i = 0; i < 2; i++) - { - - if (stair_exist[(82 + j + (i * 4)) - 82] == 1) // does this look funny to *you*? {dlb} - continue; - - do - { - pos_x = 10 + random2(GXM - 20); - pos_y = 10 + random2(GYM - 20); - } - while (grd[pos_x][pos_y] != DNGN_FLOOR - || (pos_x >= v1x && pos_x <= v2x && pos_y >= v1y - && pos_y <= v2y)); - - grd[pos_x][pos_y] = j + ((i == 0) ? DNGN_STONE_STAIRS_DOWN_I - : DNGN_STONE_STAIRS_UP_I); - } - } -} // end build_vaults() - -// returns altar_count - seems rather odd to me to force such a return -// when I believe the value is only used in the case of the ecumenical -// temple - oh, well... {dlb} -static int vault_grid( int level_number, int vx, int vy, int altar_count, - FixedVector < char, 7 > &acq_item_class, - FixedVector < int, 7 > &mons_array, - char vgrid, int &initial_x, int &initial_y, - int force_vault, int &num_runes) -{ - int not_used; - - // first, set base tile for grids {dlb}: - grd[vx][vy] = ((vgrid == 'x') ? DNGN_ROCK_WALL : - (vgrid == 'X') ? DNGN_PERMAROCK_WALL : - (vgrid == 'c') ? DNGN_STONE_WALL : - (vgrid == 'v') ? DNGN_METAL_WALL : - (vgrid == 'b') ? DNGN_GREEN_CRYSTAL_WALL : - (vgrid == 'a') ? DNGN_WAX_WALL : - (vgrid == '+') ? DNGN_CLOSED_DOOR : - (vgrid == '=') ? DNGN_SECRET_DOOR : - (vgrid == 'w') ? DNGN_DEEP_WATER : - (vgrid == 'l') ? DNGN_LAVA : - (vgrid == '>') ? DNGN_ROCK_STAIRS_DOWN : - (vgrid == '<') ? DNGN_ROCK_STAIRS_UP : - (vgrid == '}') ? DNGN_STONE_STAIRS_DOWN_I : - (vgrid == '{') ? DNGN_STONE_STAIRS_UP_I : - (vgrid == ')') ? DNGN_STONE_STAIRS_DOWN_II : - (vgrid == '(') ? DNGN_STONE_STAIRS_UP_II : - (vgrid == ']') ? DNGN_STONE_STAIRS_DOWN_III : - (vgrid == '[') ? DNGN_STONE_STAIRS_UP_III : - (vgrid == 'A') ? DNGN_STONE_ARCH : - (vgrid == 'B') ? (DNGN_ALTAR_ZIN + altar_count) :// see below - (vgrid == 'C') ? pick_an_altar() : // f(x) elsewhere {dlb} - - (vgrid == 'F') ? (one_chance_in(100) - ? (coinflip() ? DNGN_SILVER_STATUE - : DNGN_ORANGE_CRYSTAL_STATUE) - : DNGN_GRANITE_STATUE) : - - (vgrid == 'I') ? DNGN_ORCISH_IDOL : - (vgrid == 'S') ? DNGN_SILVER_STATUE : - (vgrid == 'G') ? DNGN_GRANITE_STATUE : - (vgrid == 'H') ? DNGN_ORANGE_CRYSTAL_STATUE : - (vgrid == 'T') ? DNGN_BLUE_FOUNTAIN : - (vgrid == 'U') ? DNGN_SPARKLING_FOUNTAIN : - (vgrid == 'V') ? DNGN_PERMADRY_FOUNTAIN : - (vgrid == '\0')? DNGN_ROCK_WALL : - DNGN_FLOOR); // includes everything else - - // then, handle oddball grids {dlb}: - switch (vgrid) - { - case 'B': - altar_count++; - break; - case '@': - initial_x = vx; - initial_y = vy; - break; - case '^': - place_specific_trap(vx, vy, TRAP_RANDOM); - break; - } - - // then, handle grids that place "stuff" {dlb}: - switch (vgrid) // yes, I know this is a bit ugly ... {dlb} - { - case 'R': - case '$': - case '%': - case '*': - case '|': - case 'P': // possible rune - case 'O': // definite rune - case 'Z': // definite orb - { - int item_made = NON_ITEM; - unsigned char which_class = OBJ_RANDOM; - unsigned char which_type = OBJ_RANDOM; - int which_depth; - bool possible_rune = one_chance_in(3); // lame, I know {dlb} - int spec = 250; - - if (vgrid == 'R') - { - which_class = OBJ_FOOD; - which_type = (one_chance_in(3) ? FOOD_ROYAL_JELLY - : FOOD_HONEYCOMB); - } - else if (vgrid == '$') - { - which_class = OBJ_GOLD; - which_type = OBJ_RANDOM; - } - else if (vgrid == '%' || vgrid == '*') - { - which_class = OBJ_RANDOM; - which_type = OBJ_RANDOM; - } - else if (vgrid == 'Z') - { - which_class = OBJ_ORBS; - which_type = ORB_ZOT; - } - else if (vgrid == '|' - || (vgrid == 'P' && (!possible_rune || num_runes > 0)) - || (vgrid == 'O' && num_runes > 0)) - { - which_class = acq_item_class[random2(7)]; - which_type = OBJ_RANDOM; - } - else // for 'P' (1 out of 3 times) {dlb} - { - which_class = OBJ_MISCELLANY; - which_type = MISC_RUNE_OF_ZOT; - num_runes++; - - if (you.level_type == LEVEL_PANDEMONIUM) - { - if (force_vault >= 60 && force_vault <= 63) - spec = force_vault; - else - spec = 50; - } - else if (you.level_type == LEVEL_ABYSS) - spec = 51; - else - spec = you.where_are_you; - } - - which_depth = ((vgrid == '|' - || vgrid == 'P' - || vgrid == 'O' - || vgrid == 'Z') ? MAKE_GOOD_ITEM : - (vgrid == '*') ? 5 + (level_number * 2) - : level_number); - - item_made = items( 1, which_class, which_type, true, - which_depth, spec ); - - if (item_made != NON_ITEM) - { - mitm[item_made].x = vx; - mitm[item_made].y = vy; - } - } - break; - } - - // finally, handle grids that place monsters {dlb}: - if (vgrid >= '0' && vgrid <= '9') - { - int monster_level; - int monster_type_thing; - - monster_level = ((vgrid == '8') ? (4 + (level_number * 2)) : - (vgrid == '9') ? (5 + level_number) : level_number); - - if (monster_level > 30) // very high level monsters more common here - monster_level = 30; - - monster_type_thing = ((vgrid == '8' - || vgrid == '9' - || vgrid == '0') ? RANDOM_MONSTER - : mons_array[(vgrid - '1')]); - - place_monster( not_used, monster_type_thing, monster_level, BEH_SLEEP, - MHITNOT, true, vx, vy, false); - } - - // again, this seems odd, given that this is just one of many - // vault types {dlb} - return (altar_count); -} // end vault_grid() - -static void replace_area(int sx, int sy, int ex, int ey, unsigned char replace, - unsigned char feature) -{ - int x,y; - for(x=sx; x<=ex; x++) - for(y=sy; y<=ey; y++) - if (grd[x][y] == replace) - grd[x][y] = feature; -} - -static void join_the_dots(unsigned char dotx1, unsigned char doty1, - unsigned char dotx2, unsigned char doty2, - char forbid_x1, char forbid_y1, char forbid_x2, - char forbid_y2) -{ - if (dotx1 == dotx2 && doty1 == doty2) - return; - - char atx = dotx1, aty = doty1; - - int join_count = 0; - - grd[atx][aty] = DNGN_FLOOR; - - do - { - join_count++; - - if (join_count > 10000) // just insurance - return; - - if (atx < dotx2 - && (forbid_x1 == 0 - || (atx + 1 < forbid_x1 || atx + 1 > forbid_x2 - || (aty > forbid_y2 || aty < forbid_y1)))) - { - atx++; - goto continuing; - } - - if (atx > dotx2 - && (forbid_x2 == 0 - || (atx - 1 > forbid_x2 || atx - 1 < forbid_x1 - || (aty > forbid_y2 || aty < forbid_y1)))) - { - atx--; - goto continuing; - } - - if (aty > doty2 - && (forbid_y2 == 0 - || (aty - 1 > forbid_y2 || aty - 1 < forbid_y1 - || (atx > forbid_x2 || atx < forbid_x1)))) - { - aty--; - goto continuing; - } - - if (aty < doty2 - && (forbid_y1 == 0 - || (aty + 1 < forbid_y1 || aty + 1 > forbid_y2 - || (atx > forbid_x2 || atx < forbid_x1)))) - { - aty++; - goto continuing; - } - - continuing: - grd[atx][aty] = DNGN_FLOOR; - - } - while (atx != dotx2 || aty != doty2); -} // end join_the_dots() - -static void place_pool(unsigned char pool_type, unsigned char pool_x1, - unsigned char pool_y1, unsigned char pool_x2, - unsigned char pool_y2) -{ - int i, j; - unsigned char left_edge, right_edge; - - // don't place LAVA pools in crypt.. use shallow water instead. - if (pool_type == DNGN_LAVA - && (player_in_branch(BRANCH_CRYPT) || player_in_branch(BRANCH_TOMB))) - { - pool_type = DNGN_SHALLOW_WATER; - } - - if (pool_x1 >= pool_x2 - 4 || pool_y1 >= pool_y2 - 4) - return; - - left_edge = pool_x1 + 2 + random2(pool_x2 - pool_x1); - right_edge = pool_x2 - 2 - random2(pool_x2 - pool_x1); - - for (j = pool_y1 + 1; j < pool_y2 - 1; j++) - { - for (i = pool_x1 + 1; i < pool_x2 - 1; i++) - { - if (i >= left_edge && i <= right_edge && grd[i][j] == DNGN_FLOOR) - grd[i][j] = pool_type; - } - - if (j - pool_y1 < (pool_y2 - pool_y1) / 2 || one_chance_in(4)) - { - if (left_edge > pool_x1 + 1) - left_edge -= random2(3); - - if (right_edge < pool_x2 - 1) - right_edge += random2(3); - } - - if (left_edge < pool_x2 - 1 - && (j - pool_y1 >= (pool_y2 - pool_y1) / 2 - || left_edge <= pool_x1 + 2 || one_chance_in(4))) - { - left_edge += random2(3); - } - - if (right_edge > pool_x1 + 1 - && (j - pool_y1 >= (pool_y2 - pool_y1) / 2 - || right_edge >= pool_x2 - 2 || one_chance_in(4))) - { - right_edge -= random2(3); - } - } -} // end place_pool() - -static void many_pools(unsigned char pool_type) -{ - int pools = 0; - int i = 0, j = 0, k = 0, l = 0; - int m = 0, n = 0; - int no_pools = 20 + random2avg(9, 2); - int timeout = 0; - - if (player_in_branch( BRANCH_COCYTUS )) - pool_type = DNGN_DEEP_WATER; - else if (player_in_branch( BRANCH_GEHENNA )) - pool_type = DNGN_LAVA; - - do - { - timeout++; - - if (timeout >= 30000) - break; - - i = 6 + random2( GXM - 26 ); - j = 6 + random2( GYM - 26 ); - k = i + 2 + roll_dice( 2, 9 ); - l = j + 2 + roll_dice( 2, 9 ); - - for (m = i; m < k; m++) - { - for (n = j; n < l; n++) - { - if (grd[m][n] != DNGN_FLOOR) - goto continue_pools; - } - } - - place_pool(pool_type, i, j, k, l); - pools++; - - continue_pools: - continue; - } - while (pools < no_pools); -} // end many_pools() - -void item_colour( item_def &item ) -{ - int switchnum = 0; - int temp_value; - - switch (item.base_type) - { - case OBJ_WEAPONS: - if (is_unrandom_artefact( item )) - break; // unrandarts already coloured - - if (is_fixed_artefact( item )) - { - switch (item.special) // was: - 180, but that is *wrong* {dlb} - { - case SPWPN_SINGING_SWORD: - case SPWPN_SCEPTRE_OF_TORMENT: - item.colour = YELLOW; - break; - case SPWPN_WRATH_OF_TROG: - case SPWPN_SWORD_OF_POWER: - item.colour = RED; - break; - case SPWPN_SCYTHE_OF_CURSES: - item.colour = DARKGREY; - break; - case SPWPN_MACE_OF_VARIABILITY: - item.colour = random_colour(); - break; - case SPWPN_GLAIVE_OF_PRUNE: - item.colour = MAGENTA; - break; - case SPWPN_SWORD_OF_ZONGULDROK: - item.colour = LIGHTGREY; - break; - case SPWPN_KNIFE_OF_ACCURACY: - item.colour = LIGHTCYAN; - break; - case SPWPN_STAFF_OF_OLGREB: - item.colour = GREEN; - break; - case SPWPN_VAMPIRES_TOOTH: - item.colour = WHITE; - break; - case SPWPN_STAFF_OF_WUCAD_MU: - item.colour = BROWN; - break; - } - break; - } - - if (is_demonic( item.sub_type )) - item.colour = random_colour(); - else if (launches_things( item.sub_type )) - item.colour = BROWN; - else - { - switch (item.sub_type) - { - case WPN_CLUB: - case WPN_GIANT_CLUB: - case WPN_GIANT_SPIKED_CLUB: - case WPN_ANCUS: - case WPN_WHIP: - case WPN_QUARTERSTAFF: - item.colour = BROWN; - break; - case WPN_QUICK_BLADE: - item.colour = LIGHTBLUE; - break; - case WPN_EXECUTIONERS_AXE: - item.colour = RED; - break; - default: - item.colour = LIGHTCYAN; - if (get_equip_race(item) == ISFLAG_DWARVEN) - item.colour = CYAN; - break; - } - } - - // I don't think this is ever done -- see start of case {dlb}: - if (is_random_artefact( item ) && one_chance_in(5)) - item.colour = random_colour(); - break; - - case OBJ_MISSILES: - switch (item.sub_type) - { - case MI_STONE: - case MI_LARGE_ROCK: - case MI_ARROW: - item.colour = BROWN; - break; - case MI_NEEDLE: - item.colour = WHITE; - break; - default: - item.colour = LIGHTCYAN; - if (get_equip_race(item) == ISFLAG_DWARVEN) - item.colour = CYAN; - break; - } - break; - - case OBJ_ARMOUR: - if (is_unrandom_artefact( item )) - break; /* unrandarts have already been coloured */ - - switch (item.sub_type) - { - case ARM_CLOAK: - case ARM_ROBE: - case ARM_NAGA_BARDING: - case ARM_CENTAUR_BARDING: - case ARM_CAP: - item.colour = random_colour(); - break; - - case ARM_HELMET: - //caps and wizard's hats are random coloured - if (get_helmet_type(item) == THELM_CAP - || get_helmet_type(item) == THELM_WIZARD_HAT) - { - item.colour = random_colour(); - } - else - item.colour = LIGHTCYAN; - break; - - case ARM_BOOTS: // maybe more interesting boot colours? - case ARM_GLOVES: - case ARM_LEATHER_ARMOUR: - item.colour = BROWN; - break; - case ARM_DRAGON_HIDE: - case ARM_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_DRAGON ); - break; - case ARM_TROLL_HIDE: - case ARM_TROLL_LEATHER_ARMOUR: - item.colour = mons_colour( MONS_TROLL ); - break; - case ARM_CRYSTAL_PLATE_MAIL: - item.colour = LIGHTGREY; - break; - case ARM_ICE_DRAGON_HIDE: - case ARM_ICE_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_ICE_DRAGON ); - break; - case ARM_STEAM_DRAGON_HIDE: - case ARM_STEAM_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_STEAM_DRAGON ); - break; - case ARM_MOTTLED_DRAGON_HIDE: - case ARM_MOTTLED_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_MOTTLED_DRAGON ); - break; - case ARM_STORM_DRAGON_HIDE: - case ARM_STORM_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_STORM_DRAGON ); - break; - case ARM_GOLD_DRAGON_HIDE: - case ARM_GOLD_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_GOLDEN_DRAGON ); - break; - case ARM_ANIMAL_SKIN: - item.colour = BROWN; - break; - case ARM_SWAMP_DRAGON_HIDE: - case ARM_SWAMP_DRAGON_ARMOUR: - item.colour = mons_colour( MONS_SWAMP_DRAGON ); - break; - default: - item.colour = LIGHTCYAN; - if (get_equip_race(item) == ISFLAG_DWARVEN) - item.colour = CYAN; - break; - } - - // I don't think this is ever done -- see start of case {dlb}: - if (is_random_artefact( item ) && one_chance_in(5)) - item.colour = random_colour(); - break; - - case OBJ_WANDS: - item.special = you.item_description[IDESC_WANDS][item.sub_type]; - - switch (item.special % 12) - { - case 0: //"iron wand" - item.colour = CYAN; - break; - case 1: //"brass wand" - case 5: //"gold wand" - item.colour = YELLOW; - break; - case 2: //"bone wand" - case 8: //"ivory wand" - case 9: //"glass wand" - case 10: //"lead wand" - default: - item.colour = LIGHTGREY; - break; - case 3: //"wooden wand" - case 4: //"copper wand" - case 7: //"bronze wand" - item.colour = BROWN; - break; - case 6: //"silver wand" - item.colour = WHITE; - break; - case 11: //"plastic wand" - item.colour = random_colour(); - break; - } - - if (item.special / 12 == 9) - item.colour = DARKGREY; - - // rare wands (eg disintegration - these will be very rare): - // maybe only 1 thing, like: crystal, shining, etc. - break; - - case OBJ_POTIONS: - item.special = you.item_description[IDESC_POTIONS][item.sub_type]; - - switch (item.special % 14) - { - case 0: //"clear potion" - default: - item.colour = LIGHTGREY; - break; - case 1: //"blue potion" - case 7: //"inky potion" - item.colour = BLUE; - break; - case 2: //"black potion" - item.colour = DARKGREY; - break; - case 3: //"silvery potion" - case 13: //"white potion" - item.colour = WHITE; - break; - case 4: //"cyan potion" - item.colour = CYAN; - break; - case 5: //"purple potion" - item.colour = MAGENTA; - break; - case 6: //"orange potion" - item.colour = LIGHTRED; - break; - case 8: //"red potion" - item.colour = RED; - break; - case 9: //"yellow potion" - item.colour = YELLOW; - break; - case 10: //"green potion" - item.colour = GREEN; - break; - case 11: //"brown potion" - item.colour = BROWN; - break; - case 12: //"pink potion" - item.colour = LIGHTMAGENTA; - break; - } - break; - - case OBJ_FOOD: - switch (item.sub_type) - { - case FOOD_BEEF_JERKY: - case FOOD_BREAD_RATION: - case FOOD_LYCHEE: - case FOOD_MEAT_RATION: - case FOOD_RAMBUTAN: - case FOOD_SAUSAGE: - case FOOD_SULTANA: - item.colour = BROWN; - break; - case FOOD_BANANA: - case FOOD_CHEESE: - case FOOD_HONEYCOMB: - case FOOD_LEMON: - case FOOD_PIZZA: - case FOOD_ROYAL_JELLY: - item.colour = YELLOW; - break; - case FOOD_PEAR: - item.colour = LIGHTGREEN; - break; - case FOOD_CHOKO: - case FOOD_SNOZZCUMBER: - item.colour = GREEN; - break; - case FOOD_APRICOT: - case FOOD_ORANGE: - item.colour = LIGHTRED; - break; - case FOOD_STRAWBERRY: - item.colour = RED; - break; - case FOOD_APPLE: - item.colour = (coinflip() ? RED : GREEN); - break; - case FOOD_GRAPE: - item.colour = (coinflip() ? MAGENTA : GREEN); - break; - case FOOD_CHUNK: - // set the appropriate colour of the meat: - temp_value = mons_colour( item.plus ); - item.colour = (temp_value == BLACK) ? LIGHTRED : temp_value; - break; - default: - item.colour = BROWN; - } - break; - - case OBJ_JEWELLERY: - /* unrandarts have already been coloured */ - if (is_unrandom_artefact( item )) - break; - else if (is_random_artefact( item )) - { - item.colour = random_colour(); - break; - } - - item.colour = YELLOW; - item.special = you.item_description[IDESC_RINGS][item.sub_type]; - - switchnum = item.special % 13; - - switch (switchnum) - { - case 0: - case 5: - item.colour = BROWN; - break; - case 1: - case 8: - case 11: - item.colour = LIGHTGREY; - break; - case 2: - case 6: - item.colour = YELLOW; - break; - case 3: - case 4: - item.colour = CYAN; - break; - case 7: - item.colour = BROWN; - break; - case 9: - case 10: - item.colour = WHITE; - break; - case 12: - item.colour = GREEN; - break; - case 13: - item.colour = LIGHTCYAN; - break; - } - - if (item.sub_type >= AMU_RAGE) - { - switch (switchnum) - { - case 0: //"zirconium amulet" - case 9: //"ivory amulet" - case 11: //"platinum amulet" - item.colour = WHITE; - break; - case 1: //"sapphire amulet" - item.colour = LIGHTBLUE; - break; - case 2: //"golden amulet" - case 6: //"brass amulet" - item.colour = YELLOW; - break; - case 3: //"emerald amulet" - item.colour = GREEN; - break; - case 4: //"garnet amulet" - case 8: //"ruby amulet" - item.colour = RED; - break; - case 5: //"bronze amulet" - case 7: //"copper amulet" - item.colour = BROWN; - break; - case 10: //"bone amulet" - item.colour = LIGHTGREY; - break; - case 12: //"jade amulet" - item.colour = GREEN; - break; - case 13: //"plastic amulet" - item.colour = random_colour(); - } - } - - // blackened - same for both rings and amulets - if (item.special / 13 == 5) - item.colour = DARKGREY; - break; - - case OBJ_SCROLLS: - item.colour = LIGHTGREY; - item.special = you.item_description[IDESC_SCROLLS][item.sub_type]; - item.plus = you.item_description[IDESC_SCROLLS_II][item.sub_type]; - break; - - case OBJ_BOOKS: - switch (item.special % 10) - { - case 0: - case 1: - default: - item.colour = random_colour(); - break; - case 2: - item.colour = (one_chance_in(3) ? BROWN : DARKGREY); - break; - case 3: - item.colour = CYAN; - break; - case 4: - item.colour = LIGHTGREY; - break; - } - break; - - case OBJ_STAVES: - item.colour = BROWN; - break; - - case OBJ_ORBS: - item.colour = LIGHTMAGENTA; - break; - - case OBJ_MISCELLANY: - switch (item.sub_type) - { - case MISC_BOTTLED_EFREET: - case MISC_STONE_OF_EARTH_ELEMENTALS: - item.colour = BROWN; - break; - - case MISC_AIR_ELEMENTAL_FAN: - case MISC_CRYSTAL_BALL_OF_ENERGY: - case MISC_CRYSTAL_BALL_OF_FIXATION: - case MISC_CRYSTAL_BALL_OF_SEEING: - case MISC_DISC_OF_STORMS: - case MISC_HORN_OF_GERYON: - case MISC_LANTERN_OF_SHADOWS: - item.colour = LIGHTGREY; - break; - - case MISC_LAMP_OF_FIRE: - item.colour = YELLOW; - break; - - case MISC_BOX_OF_BEASTS: - item.colour = DARKGREY; - break; - - case MISC_RUNE_OF_ZOT: - switch (item.plus) - { - case RUNE_DIS: // iron - item.colour = CYAN; - break; - - case RUNE_COCYTUS: // icy - item.colour = LIGHTBLUE; - break; - - case RUNE_TARTARUS: // bone - item.colour = WHITE; - break; - - case RUNE_SLIME_PITS: // slimy - item.colour = GREEN; - break; - - case RUNE_SNAKE_PIT: // serpentine - case RUNE_ELVEN_HALLS: // elven - item.colour = LIGHTGREEN; - break; - - case RUNE_VAULTS: // silver - item.colour = LIGHTGREY; - break; - - case RUNE_TOMB: // golden - item.colour = YELLOW; - break; - - case RUNE_SWAMP: // decaying - item.colour = BROWN; - break; - - // These two are hardly unique, but since colour isn't used for - // stacking, so we don't have to worry to much about this. -- bwr - case RUNE_DEMONIC: // random pandemonium demonlords - case RUNE_ABYSSAL: // random in abyss - item.colour = random_colour(); - break; - - case RUNE_MNOLEG: // glowing - item.colour = coinflip() ? MAGENTA : LIGHTMAGENTA; - break; - - case RUNE_LOM_LOBON: // magical - item.colour = BLUE; - break; - - case RUNE_CEREBOV: // fiery - item.colour = coinflip() ? RED : LIGHTRED; - break; - - case RUNE_GEHENNA: // obsidian - case RUNE_GLOORX_VLOQ: // dark - default: - item.colour = DARKGREY; - break; - } - break; - - case MISC_EMPTY_EBONY_CASKET: - item.colour = DARKGREY; - break; - - case MISC_DECK_OF_SUMMONINGS: - case MISC_DECK_OF_WONDERS: - case MISC_DECK_OF_TRICKS: - case MISC_DECK_OF_POWER: - default: - item.colour = random_colour(); - break; - } - break; - - case OBJ_CORPSES: - // set the appropriate colour of the body: - temp_value = mons_colour( item.plus ); - item.colour = (temp_value == BLACK) ? LIGHTRED : temp_value; - break; - - case OBJ_GOLD: - item.colour = YELLOW; - break; - } -} // end item_colour() - -// Checks how rare a weapon is. Many of these have special routines for -// placement, especially those with a rarity of zero. Chance is out of 10. -static int rare_weapon(int w_type) -{ - // zero value weapons must be placed specially -- see items() {dlb} - if (is_demonic(w_type)) - return 0; - - return (weapon_rarity(w_type)); -} // end rare_weapon() - -//jmf: generate altar based on where you are, or possibly randomly -static int pick_an_altar(void) -{ - int altar_type = 0; - int temp_rand; // probability determination {dlb} - - if (player_in_branch( BRANCH_SLIME_PITS ) - || player_in_branch( BRANCH_ECUMENICAL_TEMPLE ) - || you.level_type == LEVEL_LABYRINTH) - { - // no extra altars in temple, none at all in slime pits or labyrinth - altar_type = DNGN_FLOOR; - } - else if (you.level_type == LEVEL_DUNGEON && !one_chance_in(5)) - { - switch (you.where_are_you) - { - case BRANCH_CRYPT: - altar_type = (coinflip() ? DNGN_ALTAR_KIKUBAAQUDGHA - : DNGN_ALTAR_YREDELEMNUL); - break; - - case BRANCH_ORCISH_MINES: // violent gods - temp_rand = random2(5); - - altar_type = ((temp_rand == 0) ? DNGN_ALTAR_VEHUMET : - (temp_rand == 1) ? DNGN_ALTAR_MAKHLEB : - (temp_rand == 2) ? DNGN_ALTAR_OKAWARU : - (temp_rand == 3) ? DNGN_ALTAR_TROG - : DNGN_ALTAR_XOM); - break; - - case BRANCH_VAULTS: // "lawful" gods - temp_rand = random2(7); - - altar_type = ((temp_rand == 0) ? DNGN_ALTAR_ELYVILON : - (temp_rand == 1) ? DNGN_ALTAR_SIF_MUNA : - (temp_rand == 2) ? DNGN_ALTAR_SHINING_ONE : - (temp_rand == 3 || temp_rand == 4) ? DNGN_ALTAR_OKAWARU - : DNGN_ALTAR_ZIN); - break; - - case BRANCH_HALL_OF_BLADES: - altar_type = DNGN_ALTAR_OKAWARU; - break; - - case BRANCH_ELVEN_HALLS: // "magic" gods - temp_rand = random2(4); - - altar_type = ((temp_rand == 0) ? DNGN_ALTAR_VEHUMET : - (temp_rand == 1) ? DNGN_ALTAR_SIF_MUNA : - (temp_rand == 2) ? DNGN_ALTAR_XOM - : DNGN_ALTAR_MAKHLEB); - break; - - case BRANCH_TOMB: - altar_type = DNGN_ALTAR_KIKUBAAQUDGHA; - break; - - default: - do - { - altar_type = DNGN_ALTAR_ZIN + random2(NUM_GODS - 1); - } - while (altar_type == DNGN_ALTAR_NEMELEX_XOBEH); - break; - } - } - else - { - // Note: this case includes the pandemonium or the abyss. - temp_rand = random2(9); - - altar_type = ((temp_rand == 0) ? DNGN_ALTAR_ZIN : - (temp_rand == 1) ? DNGN_ALTAR_SHINING_ONE : - (temp_rand == 2) ? DNGN_ALTAR_KIKUBAAQUDGHA : - (temp_rand == 3) ? DNGN_ALTAR_XOM : - (temp_rand == 4) ? DNGN_ALTAR_OKAWARU : - (temp_rand == 5) ? DNGN_ALTAR_MAKHLEB : - (temp_rand == 6) ? DNGN_ALTAR_SIF_MUNA : - (temp_rand == 7) ? DNGN_ALTAR_TROG - : DNGN_ALTAR_ELYVILON); - } - - return (altar_type); -} // end pick_an_altar() - -static void place_altar(void) -{ - int px, py; - int i, j; - int k = 0, l = 0; - int altar_type = pick_an_altar(); - - while(true) - { - rand_px: - - px = 15 + random2(55); - py = 15 + random2(45); - k++; - - if (k == 5000) - return; - - l = 0; - - for (i = px - 2; i < px + 3; i++) - { - for (j = py - 2; j < py + 3; j++) - { - if (grd[i][j] == DNGN_FLOOR) - l++; - - if ((grd[i][j] != DNGN_ROCK_WALL - && grd[i][j] != DNGN_CLOSED_DOOR - && grd[i][j] != DNGN_SECRET_DOOR - && grd[i][j] != DNGN_FLOOR) - || mgrd[i][j] != NON_MONSTER) - { - goto rand_px; - } - } - } - - if (l == 0) - goto rand_px; - - for (i = px - 2; i < px + 3; i++) - { - for (j = py - 2; j < py + 3; j++) - { - grd[i][j] = DNGN_FLOOR; - } - } - - grd[px][py] = altar_type; - - return; - } -} // end place_altar() - -static void place_shops(int level_number) -{ - int temp_rand = 0; // probability determination {dlb} - int timeout = 0; - - unsigned char no_shops = 0; - unsigned char shop_place_x = 0; - unsigned char shop_place_y = 0; - - temp_rand = random2(125); - -#if DEBUG_SHOPS - no_shops = MAX_SHOPS; -#else - no_shops = ((temp_rand > 28) ? 0 : // 76.8% - (temp_rand > 4) ? 1 // 19.2% - : 1 + random2( MAX_SHOPS )); // 4.0% - - if (no_shops == 0 || level_number < 3) - return; -#endif - - for (int i = 0; i < no_shops; i++) - { - timeout = 0; - - do - { - shop_place_x = random2(GXM - 20) + 10; - shop_place_y = random2(GYM - 20) + 10; - - timeout++; - - if (timeout > 20000) - return; - } - while (grd[shop_place_x][shop_place_y] != DNGN_FLOOR); - - place_spec_shop(level_number, shop_place_x, shop_place_y, SHOP_RANDOM); - } -} // end place_shops() - -static void place_spec_shop( int level_number, - unsigned char shop_x, unsigned char shop_y, - unsigned char force_s_type ) -{ - int orb = 0; - int i = 0; - int j = 0; // loop variable - int item_level; - - for (i = 0; i < MAX_SHOPS; i++) - { - if (env.shop[i].type == SHOP_UNASSIGNED) - break; - } - - if (i == MAX_SHOPS) - return; - - for (j = 0; j < 3; j++) - { - env.shop[i].keeper_name[j] = 1 + random2(200); - } - - env.shop[i].level = level_number * 2; - - env.shop[i].type = (force_s_type != SHOP_RANDOM) ? force_s_type - : random2(NUM_SHOPS); - - if (env.shop[i].type == SHOP_FOOD) - { - env.shop[i].greed = 10 + random2(5); - } - else if (env.shop[i].type != SHOP_WEAPON_ANTIQUE - && env.shop[i].type != SHOP_ARMOUR_ANTIQUE - && env.shop[i].type != SHOP_GENERAL_ANTIQUE) - { - env.shop[i].greed = 10 + random2(5) + random2(level_number / 2); - } - else - { - env.shop[i].greed = 15 + random2avg(19, 2) + random2(level_number); - } - - int plojy = 5 + random2avg(12, 3); - - for (j = 0; j < plojy; j++) - { - if (env.shop[i].type != SHOP_WEAPON_ANTIQUE - && env.shop[i].type != SHOP_ARMOUR_ANTIQUE - && env.shop[i].type != SHOP_GENERAL_ANTIQUE) - { - item_level = level_number + random2((level_number + 1) * 2); - } - else - { - item_level = level_number + random2((level_number + 1) * 3); - } - - if (one_chance_in(4)) - item_level = MAKE_GOOD_ITEM; - - // don't generate gold in shops! This used to be possible with - // General Stores (see item_in_shop() below) (GDL) - while(true) - { - orb = items( 1, item_in_shop(env.shop[i].type), OBJ_RANDOM, true, - item_level, 250 ); - - if (orb != NON_ITEM - && mitm[orb].base_type != OBJ_GOLD - && (env.shop[i].type != SHOP_GENERAL_ANTIQUE - || (mitm[orb].base_type != OBJ_MISSILES - && mitm[orb].base_type != OBJ_FOOD))) - { - break; - } - - // reset object and try again - if (orb != NON_ITEM) - { - mitm[orb].base_type = OBJ_UNASSIGNED; - mitm[orb].quantity = 0; - } - } - - if (orb == NON_ITEM) - break; - - // set object 'position' (gah!) & ID status - mitm[orb].x = 0; - mitm[orb].y = 5 + i; - - if (env.shop[i].type != SHOP_WEAPON_ANTIQUE - && env.shop[i].type != SHOP_ARMOUR_ANTIQUE - && env.shop[i].type != SHOP_GENERAL_ANTIQUE) - { - set_ident_flags( mitm[orb], ISFLAG_IDENT_MASK ); - } - } - - env.shop[i].x = shop_x; - env.shop[i].y = shop_y; - - grd[shop_x][shop_y] = DNGN_ENTER_SHOP; -} // end place_spec_shop() - -static unsigned char item_in_shop(unsigned char shop_type) -{ - switch (shop_type) - { - case SHOP_WEAPON: - if (one_chance_in(5)) - return (OBJ_MISSILES); - // *** deliberate fall through here {dlb} *** - case SHOP_WEAPON_ANTIQUE: - return (OBJ_WEAPONS); - - case SHOP_ARMOUR: - case SHOP_ARMOUR_ANTIQUE: - return (OBJ_ARMOUR); - - case SHOP_GENERAL: - case SHOP_GENERAL_ANTIQUE: - return (OBJ_RANDOM); - - case SHOP_JEWELLERY: - return (OBJ_JEWELLERY); - - case SHOP_WAND: - return (OBJ_WANDS); - - case SHOP_BOOK: - return (OBJ_BOOKS); - - case SHOP_FOOD: - return (OBJ_FOOD); - - case SHOP_DISTILLERY: - return (OBJ_POTIONS); - - case SHOP_SCROLL: - return (OBJ_SCROLLS); - } - - return (OBJ_RANDOM); -} // end item_in_shop() - -static void spotty_level(bool seeded, int iterations, bool boxy) -{ - // assumes starting with a level full of rock walls (1) - int i, j, k, l; - - if (!seeded) - { - for (i = DNGN_STONE_STAIRS_DOWN_I; i < DNGN_ROCK_STAIRS_UP; i++) - { - if (i == DNGN_ROCK_STAIRS_DOWN - || (i == DNGN_STONE_STAIRS_UP_I - && !player_in_branch( BRANCH_SLIME_PITS ))) - { - continue; - } - - do - { - j = 10 + random2(GXM - 20); - k = 10 + random2(GYM - 20); - } - while (grd[j][k] != DNGN_ROCK_WALL - && grd[j + 1][k] != DNGN_ROCK_WALL); - - grd[j][k] = i; - - // creating elevators - if (i == DNGN_STONE_STAIRS_DOWN_I - && !player_in_branch( BRANCH_SLIME_PITS )) - { - grd[j + 1][k] = DNGN_STONE_STAIRS_UP_I; - } - - if (grd[j][k - 1] == DNGN_ROCK_WALL) - grd[j][k - 1] = DNGN_FLOOR; - if (grd[j][k + 1] == DNGN_ROCK_WALL) - grd[j][k + 1] = DNGN_FLOOR; - if (grd[j - 1][k] == DNGN_ROCK_WALL) - grd[j - 1][k] = DNGN_FLOOR; - if (grd[j + 1][k] == DNGN_ROCK_WALL) - grd[j + 1][k] = DNGN_FLOOR; - } - } // end if !seeded - - l = iterations; - - // boxy levels have more clearing, so they get fewer iterations: - if (l == 0) - l = 200 + random2( (boxy ? 750 : 1500) ); - - for (i = 0; i < l; i++) - { - do - { - j = random2(GXM - 20) + 10; - k = random2(GYM - 20) + 10; - } - while (grd[j][k] == DNGN_ROCK_WALL - && grd[j - 1][k] == DNGN_ROCK_WALL - && grd[j + 1][k] == DNGN_ROCK_WALL - && grd[j][k - 1] == DNGN_ROCK_WALL - && grd[j][k + 1] == DNGN_ROCK_WALL - && grd[j - 2][k] == DNGN_ROCK_WALL - && grd[j + 2][k] == DNGN_ROCK_WALL - && grd[j][k - 2] == DNGN_ROCK_WALL - && grd[j][k + 2] == DNGN_ROCK_WALL); - - if (grd[j][k] == DNGN_ROCK_WALL) - grd[j][k] = DNGN_FLOOR; - if (grd[j][k - 1] == DNGN_ROCK_WALL) - grd[j][k - 1] = DNGN_FLOOR; - if (grd[j][k + 1] == DNGN_ROCK_WALL) - grd[j][k + 1] = DNGN_FLOOR; - if (grd[j - 1][k] == DNGN_ROCK_WALL) - grd[j - 1][k] = DNGN_FLOOR; - if (grd[j + 1][k] == DNGN_ROCK_WALL) - grd[j + 1][k] = DNGN_FLOOR; - - if (boxy) - { - if (grd[j - 1][k - 1] == DNGN_ROCK_WALL) - grd[j - 1][k - 1] = DNGN_FLOOR; - if (grd[j + 1][k + 1] == DNGN_ROCK_WALL) - grd[j + 1][k + 1] = DNGN_FLOOR; - if (grd[j - 1][k + 1] == DNGN_ROCK_WALL) - grd[j - 1][k + 1] = DNGN_FLOOR; - if (grd[j + 1][k - 1] == DNGN_ROCK_WALL) - grd[j + 1][k - 1] = DNGN_FLOOR; - } - } -} // end spotty_level() - -static void bigger_room(void) -{ - unsigned char i, j; - - for (i = 10; i < (GXM - 10); i++) - { - for (j = 10; j < (GYM - 10); j++) - { - if (grd[i][j] == DNGN_ROCK_WALL) - grd[i][j] = DNGN_FLOOR; - } - } - - many_pools(DNGN_DEEP_WATER); - - if (one_chance_in(3)) - { - if (coinflip()) - build_river( DNGN_DEEP_WATER ); - else - build_lake( DNGN_DEEP_WATER ); - } - - int pair_count = coinflip() ? 4 : 3; - - for (j = 0; j < pair_count; j++) - { - for (i = 0; i < 2; i++) - { - place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I - : DNGN_STONE_STAIRS_UP_I) ); - } - } -} // end bigger_room() - -// various plan_xxx functions -static void plan_main(int level_number, char force_plan) -{ - // possible values for do_stairs: - // 0 - stairs already done - // 1 - stairs already done, do spotty - // 2 - no stairs - // 3 - no stairs, do spotty - char do_stairs = 0; - unsigned char special_grid = (one_chance_in(3) ? DNGN_METAL_WALL - : DNGN_STONE_WALL); - int i,j; - - if (!force_plan) - force_plan = 1 + random2(12); - - do_stairs = ((force_plan == 1) ? plan_1() : - (force_plan == 2) ? plan_2() : - (force_plan == 3) ? plan_3() : - (force_plan == 4) ? plan_4(0, 0, 0, 0, 99) : - (force_plan == 5) ? (one_chance_in(9) ? plan_5() - : plan_3()) : - (force_plan == 6) ? plan_6(level_number) - : plan_3()); - - if (do_stairs == 3 || do_stairs == 1) - spotty_level(true, 0, coinflip()); - - if (do_stairs == 2 || do_stairs == 3) - { - int pair_count = coinflip()?4:3; - - for (j = 0; j < pair_count; j++) - { - for (i = 0; i < 2; i++) - { - place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I - : DNGN_STONE_STAIRS_UP_I) ); - } - } - } - - if (one_chance_in(20)) - replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,special_grid); -} // end plan_main() - -static char plan_1(void) -{ - int temp_rand = 0; // probability determination {dlb} - - unsigned char width = (10 - random2(7)); // value range of [4,10] {dlb} - - replace_area(10, 10, (GXM - 10), (10 + width), DNGN_ROCK_WALL, DNGN_FLOOR); - replace_area(10, (60 - width), (GXM - 10), (GYM - 10), - DNGN_ROCK_WALL, DNGN_FLOOR); - replace_area(10, 10, (10 + width), (GYM - 10), DNGN_ROCK_WALL, DNGN_FLOOR); - replace_area((60 - width), 10, (GXM - 10), (GYM - 10), - DNGN_ROCK_WALL, DNGN_FLOOR); - - // possible early returns {dlb}: - temp_rand = random2(4); - - if (temp_rand > 2) // 25% chance {dlb} - return 3; - else if (temp_rand > 1) // 25% chance {dlb} - return 2; - else // 50% chance {dlb} - { - unsigned char width2 = (coinflip()? (1 + random2(5)) : 5); - - replace_area(10, (35 - width2), (GXM - 10), (35 + width2), - DNGN_ROCK_WALL, DNGN_FLOOR); - replace_area((40 - width2), 10, (40 + width2), (GYM - 10), - DNGN_ROCK_WALL, DNGN_FLOOR); - } - - // possible early returns {dlb}: - temp_rand = random2(4); - - if (temp_rand > 2) // 25% chance {dlb} - return 3; - else if (temp_rand > 1) // 25% chance {dlb} - return 2; - else // 50% chance {dlb} - { - temp_rand = random2(15); - - if (temp_rand > 7) // 7 in 15 odds {dlb} - { - spec_room sr = { false, false, 0,0,0,0 }; - sr.x1 = 25; - sr.y1 = 25; - sr.x2 = (GXM - 25); - sr.y2 = (GYM - 25); - - int oblique_max = 0; - if (coinflip()) - oblique_max = 5 + random2(20); - - temp_rand = random2(7); - - unsigned char floor_type = ((temp_rand > 1) ? DNGN_FLOOR : // 5/7 - (temp_rand > 0) ? DNGN_DEEP_WATER// 1/7 - : DNGN_LAVA); // 1/7 - octa_room(sr, oblique_max, floor_type); - } - } - - // final return {dlb}: - return (one_chance_in(5) ? 3 : 2); -} // end plan_1() - -// just a cross: -static char plan_2(void) -{ - char width2 = (5 - random2(5)); // value range of [1,5] {dlb} - - replace_area(10, (35 - width2), (GXM - 10), (35 + width2), - DNGN_ROCK_WALL, DNGN_FLOOR); - replace_area((40 - width2), 10, (40 + width2), (GYM - 10), - DNGN_ROCK_WALL, DNGN_FLOOR); - - return (one_chance_in(4) ? 2 : 3); -} // end plan_2() - -static char plan_3(void) -{ - - /* Draws a room, then another and links them together, then another and etc - Of course, this can easily end up looking just like a make_trail level. - */ - int i; - char cnx, cny; - int roomsss = 30 + random2(90); - - bool exclusive = (one_chance_in(10) ? false : true); - bool exclusive2 = coinflip(); - - char romx1[30], romy1[30], romx2[30], romy2[30]; - - int which_room = 0; - - for (i = 0; i < roomsss; i++) - { - romx1[which_room] = 10 + random2(50); - romy1[which_room] = 10 + random2(40); - romx2[which_room] = romx1[which_room] + 2 + random2(8); - romy2[which_room] = romy1[which_room] + 2 + random2(8); - - if (exclusive) - { - for (cnx = romx1[which_room] - 1; cnx < romx2[which_room] + 1; - cnx++) - { - for (cny = romy1[which_room] - 1; cny < romy2[which_room] + 1; - cny++) - { - if (grd[cnx][cny] != DNGN_ROCK_WALL) - goto continuing; - } - } - } - - replace_area(romx1[which_room], romy1[which_room], romx2[which_room], - romy2[which_room], DNGN_ROCK_WALL, DNGN_FLOOR); - - if (which_room > 0 && !exclusive2) - { - const int rx1 = romx1[which_room]; - const int rx2 = romx2[which_room]; - const int prev_rx1 = romx1[which_room - 1]; - const int prev_rx2 = romx2[which_room - 1]; - - const int ry1 = romy1[which_room]; - const int ry2 = romy2[which_room]; - const int prev_ry1 = romy1[which_room - 1]; - const int prev_ry2 = romy2[which_room - 1]; - - join_the_dots( rx1 + random2( rx2 - rx1 ), - ry1 + random2( ry2 - ry1 ), - prev_rx1 + random2( prev_rx2 - prev_rx1 ), - prev_ry1 + random2( prev_ry2 - prev_ry1 ), - 0, 0, 0, 0 ); - } - - which_room++; - - if (which_room >= 29) - break; - - continuing: - continue; - } - - if (exclusive2) - { - for (i = 0; i < which_room; i++) - { - if (i > 0) - { - const int rx1 = romx1[i]; - const int rx2 = romx2[i]; - const int prev_rx1 = romx1[i - 1]; - const int prev_rx2 = romx2[i - 1]; - - const int ry1 = romy1[i]; - const int ry2 = romy2[i]; - const int prev_ry1 = romy1[i - 1]; - const int prev_ry2 = romy2[i - 1]; - - join_the_dots( rx1 + random2( rx2 - rx1 ), - ry1 + random2( ry2 - ry1 ), - prev_rx1 + random2( prev_rx2 - prev_rx1 ), - prev_ry1 + random2( prev_ry2 - prev_ry1 ), - 0, 0, 0, 0 ); - } - } - } - - return 2; -} // end plan_3() - -static char plan_4(char forbid_x1, char forbid_y1, char forbid_x2, - char forbid_y2, unsigned char force_wall) -{ - // a more chaotic version of city level - int temp_rand; // req'd for probability checking - - int number_boxes = 5000; - unsigned char drawing = DNGN_ROCK_WALL; - char b1x, b1y, b2x, b2y; - char cnx, cny; - int i; - - temp_rand = random2(81); - - number_boxes = ((temp_rand > 48) ? 4000 : // odds: 32 in 81 {dlb} - (temp_rand > 24) ? 3000 : // odds: 24 in 81 {dlb} - (temp_rand > 8) ? 5000 : // odds: 16 in 81 {dlb} - (temp_rand > 0) ? 2000 // odds: 8 in 81 {dlb} - : 1000); // odds: 1 in 81 {dlb} - - if (force_wall != 99) - drawing = force_wall; - else - { - temp_rand = random2(18); - - drawing = ((temp_rand > 7) ? DNGN_ROCK_WALL : // odds: 10 in 18 {dlb} - (temp_rand > 2) ? DNGN_STONE_WALL // odds: 5 in 18 {dlb} - : DNGN_METAL_WALL); // odds: 3 in 18 {dlb} - } - - replace_area(10, 10, (GXM - 10), (GYM - 10), DNGN_ROCK_WALL, DNGN_FLOOR); - - // replace_area can also be used to fill in: - for (i = 0; i < number_boxes; i++) - { - - b1x = 11 + random2(45); - b1y = 11 + random2(35); - - b2x = b1x + 3 + random2(7) + random2(5); - b2y = b1y + 3 + random2(7) + random2(5); - - if (forbid_x1 != 0 || forbid_x2 != 0) - { - if (b1x <= forbid_x2 && b1x >= forbid_x1 - && b1y <= forbid_y2 && b1y >= forbid_y1) - { - goto continuing; - } - else if (b2x <= forbid_x2 && b2x >= forbid_x1 - && b2y <= forbid_y2 && b2y >= forbid_y1) - { - goto continuing; - } - } - - for (cnx = b1x - 1; cnx < b2x + 1; cnx++) - { - for (cny = b1y - 1; cny < b2y + 1; cny++) - { - if (grd[cnx][cny] != DNGN_FLOOR) - goto continuing; - } - } - - if (force_wall == 99) - { - // NB: comparison reversal here - combined - temp_rand = random2(1200); - - // probabilities *not meant* to sum to one! {dlb} - if (temp_rand < 417) // odds: 261 in 1200 {dlb} - drawing = DNGN_ROCK_WALL; - else if (temp_rand < 156) // odds: 116 in 1200 {dlb} - drawing = DNGN_STONE_WALL; - else if (temp_rand < 40) // odds: 40 in 1200 {dlb} - drawing = DNGN_METAL_WALL; - } - - temp_rand = random2(210); - - if (temp_rand > 71) // odds: 138 in 210 {dlb} - replace_area(b1x, b1y, b2x, b2y, DNGN_FLOOR, drawing); - else // odds: 72 in 210 {dlb} - box_room(b1x, b2x - 1, b1y, b2y - 1, drawing); - - continuing: - continue; - } - - if (forbid_x1 == 0 && one_chance_in(4)) // a market square - { - spec_room sr = { false, false, 0, 0, 0, 0 }; - sr.x1 = 25; - sr.y1 = 25; - sr.x2 = 55; - sr.y2 = 45; - - int oblique_max = 0; - if (!one_chance_in(4)) - oblique_max = 5 + random2(20); // used elsewhere {dlb} - - unsigned char feature = DNGN_FLOOR; - if (one_chance_in(10)) - feature = coinflip()? DNGN_DEEP_WATER : DNGN_LAVA; - - octa_room(sr, oblique_max, feature); - } - - return 2; -} // end plan_4() - -static char plan_5(void) -{ - unsigned char imax = 5 + random2(20); // value range of [5,24] {dlb} - - for (unsigned char i = 0; i < imax; i++) - { - join_the_dots( random2(GXM - 20) + 10, random2(GYM - 20) + 10, - random2(GXM - 20) + 10, random2(GYM - 20) + 10, - 0, 0, 0, 0 ); - } - - if (!one_chance_in(4)) - spotty_level(true, 100, coinflip()); - - return 2; -} // end plan_5() - -static char plan_6(int level_number) -{ - spec_room sr = { false, false, 0,0,0,0 }; - - // circle of standing stones (well, kind of) - sr.x1 = 10; - sr.x2 = (GXM - 10); - sr.y1 = 10; - sr.y2 = (GYM - 10); - - octa_room(sr, 14, DNGN_FLOOR); - - replace_area(23, 23, 26, 26, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(23, 47, 26, 50, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(55, 23, 58, 26, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(55, 47, 58, 50, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(39, 20, 43, 23, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(39, 50, 43, 53, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(20, 30, 23, 33, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(20, 40, 23, 43, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(58, 30, 61, 33, DNGN_FLOOR, DNGN_STONE_WALL); - replace_area(58, 40, 61, 43, DNGN_FLOOR, DNGN_STONE_WALL); - - grd[35][32] = DNGN_STONE_WALL; - grd[46][32] = DNGN_STONE_WALL; - grd[35][40] = DNGN_STONE_WALL; - grd[46][40] = DNGN_STONE_WALL; - - grd[69][34] = DNGN_STONE_STAIRS_DOWN_I; - grd[69][35] = DNGN_STONE_STAIRS_DOWN_II; - grd[69][36] = DNGN_STONE_STAIRS_DOWN_III; - - grd[10][34] = DNGN_STONE_STAIRS_UP_I; - grd[10][35] = DNGN_STONE_STAIRS_UP_II; - grd[10][36] = DNGN_STONE_STAIRS_UP_III; - - // This "back door" is often one of the easier ways to get out of - // pandemonium... the easiest is to use the banish spell. - // - // Note, that although "level_number > 20" will work for most - // trips to pandemonium (through regular portals), it won't work - // for demonspawn who gate themselves there. -- bwr - if (((player_in_branch( BRANCH_MAIN_DUNGEON ) && level_number > 20) - || you.level_type == LEVEL_PANDEMONIUM) - && (coinflip() || you.mutation[ MUT_PANDEMONIUM ])) - { - grd[40][36] = DNGN_ENTER_ABYSS; - grd[41][36] = DNGN_ENTER_ABYSS; - } - - return 0; -} // end plan_6() - -static bool octa_room(spec_room &sr, int oblique_max, unsigned char type_floor) -{ - int x,y; - - // hack - avoid lava in the crypt {gdl} - if ((player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) - && type_floor == DNGN_LAVA) - { - type_floor = DNGN_SHALLOW_WATER; - } - - int oblique = oblique_max; - - // check octagonal room for special; avoid if exists - for (x = sr.x1; x < sr.x2; x++) - { - for (y = sr.y1 + oblique; y < sr.y2 - oblique; y++) - { - if (grd[x][y] == DNGN_BUILDER_SPECIAL_WALL) - return false; - } - - if (oblique > 0) - oblique--; - - if (x > sr.x2 - oblique_max) - oblique += 2; - } - - oblique = oblique_max; - - - for (x = sr.x1; x < sr.x2; x++) - { - for (y = sr.y1 + oblique; y < sr.y2 - oblique; y++) - { - if (grd[x][y] == DNGN_ROCK_WALL) - grd[x][y] = type_floor; - - if (grd[x][y] == DNGN_FLOOR && type_floor == DNGN_SHALLOW_WATER) - grd[x][y] = DNGN_SHALLOW_WATER; - - if (grd[x][y] == DNGN_CLOSED_DOOR && type_floor >= MINMOVE) - grd[x][y] = DNGN_FLOOR; // ick - } - - if (oblique > 0) - oblique--; - - if (x > sr.x2 - oblique_max) - oblique += 2; - } - - return true; -} // end octa_room() - -static void labyrinth_level(int level_number) -{ - int temp_rand; // probability determination {dlb} - - int keep_lx = 0, keep_ly = 0; - int keep_lx2 = 0, keep_ly2 = 0; - char start_point_x = 10; - char start_point_y = 10; - char going_x = 1; - char going_y = (coinflip() ? 0 : 1); - bool do_2 = false; - int clear_space = 1; - unsigned char traps_put2 = 0; - - if (coinflip()) - { - start_point_x = (GXM - 10); - going_x = -1; - } - - if (coinflip()) - { - start_point_y = (GYM - 10); - - if (going_y == 1) - going_y = -1; - } - - int lx = start_point_x; - int ly = start_point_y; - - if (going_y) - goto do_y; - - do_x: - traps_put2 = 0; - clear_space = 0; // ( coinflip()? 3 : 2 ); - - do - { - lx += going_x; - - if (grd[lx][ly] == DNGN_ROCK_WALL) - grd[lx][ly] = DNGN_FLOOR; - } - while (lx < (GXM - 8) && lx > 8 - && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL); - - going_x = 0; - - if (ly < 32) - going_y = 1; - else if (ly > 37) - going_y = -1; - else - goto finishing; - - do_y: // if (going_y != 0) - if (do_2) - { - lx = keep_lx2; - ly = keep_ly2; - } - - // do_2 = false is the problem - if (coinflip()) - { - clear_space = 0; - do_2 = false; - } - else - { - clear_space = 2; - do_2 = true; - } - - do - { - ly += going_y; - - if (grd[lx][ly] == DNGN_ROCK_WALL) - grd[lx][ly] = DNGN_FLOOR; - } - while (ly < (GYM - 8) && ly > 8 - && grd[lx][ly + going_y * (2 + clear_space)] == DNGN_ROCK_WALL); - - keep_lx = lx; - keep_ly = ly; - - if (lx < 37) - going_x = 1; - else if (lx > 42) - going_x = -1; - - if (ly < 33) - ly += 2; - else if (ly > 37) - ly -= 2; - - clear_space = ((!do_2) ? 6 : 2); - - do - { - lx += going_x; - - if (grd[lx][ly] == DNGN_ROCK_WALL) - grd[lx][ly] = DNGN_FLOOR; - } - while (lx < (GXM - 8) && lx > 8 - && grd[lx + going_x * (2 + clear_space)][ly] == DNGN_ROCK_WALL); - - if (do_2) - { - keep_lx2 = lx; - keep_ly2 = ly; - } - - lx = keep_lx; - ly = keep_ly; - - going_y = 0; - - if (lx < 37) - going_x = 1; - else if (lx > 42) - going_x = -1; - else - goto finishing; - - goto do_x; - - finishing: - start_point_x = 10 + random2(GXM - 20); - - int treasure_item = 0; - - unsigned char glopop = OBJ_RANDOM; // used in calling items() {dlb} - - int num_items = 8 + random2avg(9, 2); - for (int i = 0; i < num_items; i++) - { - temp_rand = random2(11); - - glopop = ((temp_rand == 0 || temp_rand == 9) ? OBJ_WEAPONS : - (temp_rand == 1 || temp_rand == 10) ? OBJ_ARMOUR : - (temp_rand == 2) ? OBJ_MISSILES : - (temp_rand == 3) ? OBJ_WANDS : - (temp_rand == 4) ? OBJ_MISCELLANY : - (temp_rand == 5) ? OBJ_SCROLLS : - (temp_rand == 6) ? OBJ_JEWELLERY : - (temp_rand == 7) ? OBJ_BOOKS - /* (temp_rand == 8) */ : OBJ_STAVES); - - treasure_item = items( 1, glopop, OBJ_RANDOM, true, - level_number * 3, 250 ); - - if (treasure_item != NON_ITEM) - { - mitm[treasure_item].x = lx; - mitm[treasure_item].y = ly; - } - } - - mons_place( MONS_MINOTAUR, BEH_SLEEP, MHITNOT, true, lx, ly ); - - grd[lx][ly] = DNGN_ROCK_STAIRS_UP; - - link_items(); - - // turn rock walls into undiggable stone or metal: - temp_rand = random2(50); - - unsigned char wall_xform = ((temp_rand > 10) ? DNGN_STONE_WALL // 78.0% - : DNGN_METAL_WALL); // 22.0% - - replace_area(0,0,GXM-1,GYM-1,DNGN_ROCK_WALL,wall_xform); - -} // end labyrinth_level() - -static bool is_wall(int x, int y) -{ - unsigned char feat = grd[x][y]; - - switch (feat) - { - case DNGN_ROCK_WALL: - case DNGN_STONE_WALL: - case DNGN_METAL_WALL: - case DNGN_GREEN_CRYSTAL_WALL: - case DNGN_WAX_WALL: - return true; - default: - return false; - } -} - - -static int box_room_door_spot(int x, int y) -{ - // if there is a door near us embedded in rock, we have to be a door too. - if ((grd[x-1][y] == DNGN_CLOSED_DOOR && is_wall(x-1,y-1) && is_wall(x-1,y+1)) - || (grd[x+1][y] == DNGN_CLOSED_DOOR && is_wall(x+1,y-1) && is_wall(x+1,y+1)) - || (grd[x][y-1] == DNGN_CLOSED_DOOR && is_wall(x-1,y-1) && is_wall(x+1,y-1)) - || (grd[x][y+1] == DNGN_CLOSED_DOOR && is_wall(x-1,y+1) && is_wall(x+1,y+1))) - { - grd[x][y] = DNGN_CLOSED_DOOR; - return 2; - } - - // to be a good spot for a door, we need non-wall on two sides and - // wall on two sides. - bool nor = is_wall(x, y-1); - bool sou = is_wall(x, y+1); - bool eas = is_wall(x-1, y); - bool wes = is_wall(x+1, y); - - if (nor == sou && eas == wes && nor != eas) - return 1; - - return 0; -} - -static int box_room_doors( int bx1, int bx2, int by1, int by2, int new_doors) -{ - int good_doors[200]; // 1 == good spot, 2 == door placed! - int spot; - int i,j; - int doors_placed = new_doors; - - // sanity - if ( 2 * ( (bx2 - bx1) + (by2-by1) ) > 200) - return 0; - - // go through, building list of good door spots, and replacing wall - // with door if we're about to block off another door. - int spot_count = 0; - - // top & bottom - for(i=bx1+1; i<bx2; i++) - { - good_doors[spot_count ++] = box_room_door_spot(i, by1); - good_doors[spot_count ++] = box_room_door_spot(i, by2); - } - // left & right - for(i=by1+1; i<by2; i++) - { - good_doors[spot_count ++] = box_room_door_spot(bx1, i); - good_doors[spot_count ++] = box_room_door_spot(bx2, i); - } - - if (new_doors == 0) - { - // count # of doors we HAD to place - for(i=0; i<spot_count; i++) - if (good_doors[i] == 2) - doors_placed++; - - return doors_placed; - } - - // Avoid an infinite loop if there are not enough good spots. --KON - j = 0; - for (i=0; i<spot_count; i++) - if (good_doors[i] == 1) - j++; - if (new_doors > j) - new_doors = j; - - while(new_doors > 0 && spot_count > 0) - { - spot = random2(spot_count); - if (good_doors[spot] != 1) - continue; - - j = 0; - for(i=bx1+1; i<bx2; i++) - { - if (spot == j++) - { - grd[i][by1] = DNGN_CLOSED_DOOR; - break; - } - if (spot == j++) - { - grd[i][by2] = DNGN_CLOSED_DOOR; - break; - } - } - - for(i=by1+1; i<by2; i++) - { - if (spot == j++) - { - grd[bx1][i] = DNGN_CLOSED_DOOR; - break; - } - if (spot == j++) - { - grd[bx2][i] = DNGN_CLOSED_DOOR; - break; - } - } - - // try not to put a door in the same place twice - good_doors[spot] = 2; - new_doors --; - } - - return doors_placed; -} - - -static void box_room(int bx1, int bx2, int by1, int by2, int wall_type) -{ - // hack -- avoid lava in the crypt. {gdl} - if ((player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) - && wall_type == DNGN_LAVA) - { - wall_type = DNGN_SHALLOW_WATER; - } - - int temp_rand, new_doors, doors_placed; - - // do top & bottom walls - replace_area(bx1,by1,bx2,by1,DNGN_FLOOR,wall_type); - replace_area(bx1,by2,bx2,by2,DNGN_FLOOR,wall_type); - - // do left & right walls - replace_area(bx1,by1+1,bx1,by2-1,DNGN_FLOOR,wall_type); - replace_area(bx2,by1+1,bx2,by2-1,DNGN_FLOOR,wall_type); - - // sometimes we have to place doors, or else we shut in other buildings' doors - doors_placed = box_room_doors(bx1, bx2, by1, by2, 0); - - temp_rand = random2(100); - new_doors = (temp_rand > 45) ? 2 : - ((temp_rand > 22) ? 1 : 3); - - // small rooms don't have as many doors - if ((bx2-bx1)*(by2-by1) < 36) - new_doors--; - - new_doors -= doors_placed; - if (new_doors > 0) - box_room_doors(bx1, bx2, by1, by2, new_doors); -} - -static void city_level(int level_number) -{ - int temp_rand; // probability determination {dlb} - int wall_type; // remember, can have many wall types in one level - int wall_type_room; // simplifies logic of innermost loop {dlb} - - int xs = 0, ys = 0; - int x1 = 0, x2 = 0; - int y1 = 0, y2 = 0; - int i,j; - - temp_rand = random2(8); - - wall_type = ((temp_rand > 4) ? DNGN_ROCK_WALL : // 37.5% {dlb} - (temp_rand > 1) ? DNGN_STONE_WALL // 37.5% {dlb} - : DNGN_METAL_WALL); // 25.0% {dlb} - - if (one_chance_in(100)) - wall_type = DNGN_GREEN_CRYSTAL_WALL; - - make_box( 7, 7, GXM-7, GYM-7, DNGN_FLOOR ); - - for (i = 0; i < 5; i++) - { - for (j = 0; j < 4; j++) - { - xs = 8 + (i * 13); - ys = 8 + (j * 14); - x1 = xs + random2avg(5, 2); - y1 = ys + random2avg(5, 2); - x2 = xs + 11 - random2avg(5, 2); - y2 = ys + 11 - random2avg(5, 2); - - temp_rand = random2(280); - - if (temp_rand > 39) // 85.7% draw room(s) {dlb} - { - wall_type_room = ((temp_rand > 63) ? wall_type : // 77.1% - (temp_rand > 54) ? DNGN_STONE_WALL : // 3.2% - (temp_rand > 45) ? DNGN_ROCK_WALL // 3.2% - : DNGN_METAL_WALL); // 2.1% - - if (one_chance_in(250)) - wall_type_room = DNGN_GREEN_CRYSTAL_WALL; - - box_room(x1, x2, y1, y2, wall_type_room); - - // inner room - neat. - if (x2 - x1 > 5 && y2 - y1 > 5 && one_chance_in(8)) - { - box_room(x1 + 2, x2 - 2, y1 + 2, y2 - 2, wall_type); - - // treasure area.. neat. - if (one_chance_in(3)) - treasure_area(level_number, x1 + 3, x2 - 3, y1 + 3, y2 - 3); - } - } - } - } - - int stair_count = coinflip() ? 2 : 1; - - for (j = 0; j < stair_count; j++) - { - for (i = 0; i < 2; i++) - { - place_specific_stair( j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I - : DNGN_STONE_STAIRS_UP_I) ); - } - } - -} // end city_level() - -static bool treasure_area(int level_number, unsigned char ta1_x, - unsigned char ta2_x, unsigned char ta1_y, - unsigned char ta2_y) -{ - int x_count = 0; - int y_count = 0; - int item_made = 0; - - ta2_x++; - ta2_y++; - - if (ta2_x <= ta1_x || ta2_y <= ta1_y) - return false; - - if ((ta2_x - ta1_x) * (ta2_y - ta1_y) >= 40) - return false; - - for (x_count = ta1_x; x_count < ta2_x; x_count++) - { - for (y_count = ta1_y; y_count < ta2_y; y_count++) - { - if (grd[x_count][y_count] != DNGN_FLOOR || coinflip()) - continue; - - item_made = items( 1, OBJ_RANDOM, OBJ_RANDOM, true, - random2( level_number * 2 ), 250 ); - - if (item_made != NON_ITEM) - { - mitm[item_made].x = x_count; - mitm[item_made].y = y_count; - } - } - } - - return true; -} // end treasure_area() - -static void diamond_rooms(int level_number) -{ - char numb_diam = 1 + random2(10); - char type_floor = DNGN_DEEP_WATER; - int runthru = 0; - int i, oblique_max; - - // I guess no diamond rooms in either of these places {dlb}: - if (player_in_branch( BRANCH_DIS ) || player_in_branch( BRANCH_TARTARUS )) - return; - - if (level_number > 5 + random2(5) && coinflip()) - type_floor = DNGN_SHALLOW_WATER; - - if (level_number > 10 + random2(5) && coinflip()) - type_floor = DNGN_DEEP_WATER; - - if (level_number > 17 && coinflip()) - type_floor = DNGN_LAVA; - - if (level_number > 10 && one_chance_in(15)) - type_floor = (coinflip()? DNGN_STONE_WALL : DNGN_ROCK_WALL); - - if (level_number > 12 && one_chance_in(20)) - type_floor = DNGN_METAL_WALL; - - if (player_in_branch( BRANCH_GEHENNA )) - type_floor = DNGN_LAVA; - else if (player_in_branch( BRANCH_COCYTUS )) - type_floor = DNGN_DEEP_WATER; - - for (i = 0; i < numb_diam; i++) - { - spec_room sr = { false, false, 0, 0, 0, 0 }; - - sr.x1 = 8 + random2(43); - sr.y1 = 8 + random2(35); - sr.x2 = sr.x1 + 5 + random2(15); - sr.y2 = sr.y1 + 5 + random2(10); - - oblique_max = (sr.x2 - sr.x1) / 2; //random2(20) + 5; - - if (!octa_room(sr, oblique_max, type_floor)) - { - runthru++; - if (runthru > 9) - { - runthru = 0; - } - else - { - i--; - continue; - } - } - } // end "for(bk...)" -} // end diamond_rooms() - -static void big_room(int level_number) -{ - unsigned char type_floor = DNGN_FLOOR; - unsigned char type_2 = DNGN_FLOOR; - int i, j, k, l; - - spec_room sr = { false, false, 0, 0, 0, 0 }; - int oblique; - - if (one_chance_in(4)) - { - oblique = 5 + random2(20); - - sr.x1 = 8 + random2(30); - sr.y1 = 8 + random2(22); - sr.x2 = sr.x1 + 20 + random2(10); - sr.y2 = sr.y1 + 20 + random2(8); - - // usually floor, except at higher levels - if (!one_chance_in(5) || level_number < 8 + random2(8)) - { - octa_room(sr, oblique, DNGN_FLOOR); - return; - } - - // default is lava. - type_floor = DNGN_LAVA; - - if (level_number > 7) - { - type_floor = ((random2(level_number) < 14) ? DNGN_DEEP_WATER - : DNGN_LAVA); - } - - octa_room(sr, oblique, type_floor); - } - - // what now? - sr.x1 = 8 + random2(30); - sr.y1 = 8 + random2(22); - sr.x2 = sr.x1 + 20 + random2(10); - sr.y2 = sr.y1 + 20 + random2(8); - - // check for previous special - if (find_in_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_BUILDER_SPECIAL_WALL)) - return; - - if (level_number > 7 && one_chance_in(4)) - { - type_floor = ((random2(level_number) < 14) ? DNGN_DEEP_WATER - : DNGN_LAVA); - } - - // make the big room. - replace_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_ROCK_WALL, type_floor); - replace_area(sr.x1, sr.y1, sr.x2, sr.y2, DNGN_CLOSED_DOOR, type_floor); - - if (type_floor == DNGN_FLOOR) - type_2 = DNGN_ROCK_WALL + random2(4); - - // no lava in the Crypt or Tomb, thanks! - if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) - { - if (type_floor == DNGN_LAVA) - type_floor = DNGN_SHALLOW_WATER; - - if (type_2 == DNGN_LAVA) - type_2 = DNGN_SHALLOW_WATER; - } - - // sometimes make it a chequerboard - if (one_chance_in(4)) - { - chequerboard( sr, type_floor, type_floor, type_2 ); - } - // sometimes make an inside room w/ stone wall. - else if (one_chance_in(6)) - { - i = sr.x1; - j = sr.y1; - k = sr.x2; - l = sr.y2; - - do - { - i += 2 + random2(3); - j += 2 + random2(3); - k -= 2 + random2(3); - l -= 2 + random2(3); - // check for too small - if (i >= k - 3) - break; - if (j >= l - 3) - break; - - box_room(i, k, j, l, DNGN_STONE_WALL); - - } - while (level_number < 1500); // ie forever - } -} // end big_room() - -// helper function for chequerboard rooms -// note that box boundaries are INclusive -static void chequerboard( spec_room &sr, unsigned char target, - unsigned char floor1, unsigned char floor2 ) -{ - int i, j; - - if (sr.x2 < sr.x1 || sr.y2 < sr.y1) - return; - - for (i = sr.x1; i <= sr.x2; i++) - { - for (j = sr.y1; j <= sr.y2; j++) - { - if (grd[i][j] == target) - grd[i][j] = (((i + j) % 2) ? floor2 : floor1); - } - } -} // end chequerboard() - -static void roguey_level(int level_number, spec_room &sr) -{ - int bcount_x, bcount_y; - int cn = 0; - int i; - - FixedVector < unsigned char, 30 > rox1; - FixedVector < unsigned char, 30 > rox2; - FixedVector < unsigned char, 30 > roy1; - FixedVector < unsigned char, 30 > roy2; - - for (bcount_y = 0; bcount_y < 5; bcount_y++) - { - for (bcount_x = 0; bcount_x < 5; bcount_x++) - { - // rooms: - rox1[cn] = bcount_x * 13 + 8 + random2(4); - roy1[cn] = bcount_y * 11 + 8 + random2(4); - - rox2[cn] = rox1[cn] + 3 + random2(8); - roy2[cn] = roy1[cn] + 3 + random2(6); - - // bounds - if (rox2[cn] > GXM-8) - rox2[cn] = GXM-8; - - cn++; - } - } - - cn = 0; - - for (i = 0; i < 25; i++) - { - replace_area( rox1[i], roy1[i], rox2[i], roy2[i], - DNGN_ROCK_WALL, DNGN_FLOOR ); - - // inner room? - if (rox2[i] - rox1[i] > 5 && roy2[i] - roy1[i] > 5) - { - if (random2(100 - level_number) < 3) - { - if (!one_chance_in(4)) - { - box_room( rox1[i] + 2, rox2[i] - 2, roy1[i] + 2, - roy2[i] - 2, (coinflip() ? DNGN_STONE_WALL - : DNGN_ROCK_WALL) ); - } - else - { - box_room( rox1[i] + 2, rox2[i] - 2, roy1[i] + 2, - roy2[i] - 2, DNGN_METAL_WALL ); - } - - if (coinflip()) - { - treasure_area( level_number, rox1[i] + 3, rox2[i] - 3, - roy1[i] + 3, roy2[i] - 3 ); - } - } - } - } // end "for i" - - // Now, join them together: - FixedVector < char, 2 > pos; - FixedVector < char, 2 > jpos; - - char doing = 0; - - char last_room = 0; - int bp; - - for (bp = 0; bp < 2; bp++) - { - for (i = 0; i < 25; i++) - { - if (bp == 0 && (!(i % 5) || i == 0)) - continue; - - if (bp == 1 && i < 5) - continue; - - switch (bp) - { - case 0: - last_room = i - 1; - pos[0] = rox1[i]; // - 1; - pos[1] = roy1[i] + random2(roy2[i] - roy1[i]); - jpos[0] = rox2[last_room]; // + 1; - jpos[1] = roy1[last_room] - + random2(roy2[last_room] - roy1[last_room]); - break; - - case 1: - last_room = i - 5; - pos[1] = roy1[i]; // - 1; - pos[0] = rox1[i] + random2(rox2[i] - rox1[i]); - jpos[1] = roy2[last_room]; // + 1; - jpos[0] = rox1[last_room] - + random2(rox2[last_room] - rox1[last_room]); - break; - } - - while (pos[0] != jpos[0] || pos[1] != jpos[1]) - { - doing = (coinflip()? 1 : 0); - - if (pos[doing] < jpos[doing]) - pos[doing]++; - else if (pos[doing] > jpos[doing]) - pos[doing]--; - - if (grd[pos[0]][pos[1]] == DNGN_ROCK_WALL) - grd[pos[0]][pos[1]] = DNGN_FLOOR; - } - - if (grd[pos[0]][pos[1]] == DNGN_FLOOR) - { - if ((grd[pos[0] + 1][pos[1]] == DNGN_ROCK_WALL - && grd[pos[0] - 1][pos[1]] == DNGN_ROCK_WALL) - || (grd[pos[0]][pos[1] + 1] == DNGN_ROCK_WALL - && grd[pos[0]][pos[1] - 1] == DNGN_ROCK_WALL)) - { - grd[pos[0]][pos[1]] = 103; - } - } - } // end "for bp, for i" - } - - // is one of them a special room? - if (level_number > 8 && one_chance_in(10)) - { - int spec_room_done = random2(25); - - sr.created = true; - sr.hooked_up = true; - sr.x1 = rox1[spec_room_done]; - sr.x2 = rox2[spec_room_done]; - sr.y1 = roy1[spec_room_done]; - sr.y2 = roy2[spec_room_done]; - special_room( level_number, sr ); - - // make the room 'special' so it doesn't get overwritten - // by something else (or put monsters in walls, etc..). - - // top - replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - replace_area(sr.x1-1, sr.y1-1, sr.x2+1,sr.y1-1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); - - // bottom - replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - replace_area(sr.x1-1, sr.y2+1, sr.x2+1,sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); - - // left - replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - replace_area(sr.x1-1, sr.y1-1, sr.x1-1, sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); - - // right - replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_ROCK_WALL, DNGN_BUILDER_SPECIAL_WALL); - replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_FLOOR, DNGN_BUILDER_SPECIAL_FLOOR); - replace_area(sr.x2+1, sr.y1-1, sr.x2+1, sr.y2+1, DNGN_CLOSED_DOOR, DNGN_BUILDER_SPECIAL_FLOOR); - } - - int stair_count = coinflip() ? 2 : 1; - - for (int j = 0; j < stair_count; j++) - { - for (i = 0; i < 2; i++) - { - place_specific_stair(j + ((i==0) ? DNGN_STONE_STAIRS_DOWN_I - : DNGN_STONE_STAIRS_UP_I)); - } - } -} // end roguey_level() - -static void morgue(spec_room &sr) -{ - int temp_rand = 0; // probability determination {dlb} - int x,y; - - for (x = sr.x1; x <= sr.x2; x++) - { - for (y = sr.y1; y <= sr.y2; y++) - { - if (grd[x][y] == DNGN_FLOOR || grd[x][y] == DNGN_BUILDER_SPECIAL_FLOOR) - { - int mon_type; - temp_rand = random2(24); - - mon_type = ((temp_rand > 11) ? MONS_ZOMBIE_SMALL : // 50.0% - (temp_rand > 7) ? MONS_WIGHT : // 16.7% - (temp_rand > 3) ? MONS_NECROPHAGE : // 16.7% - (temp_rand > 0) ? MONS_WRAITH // 12.5% - : MONS_VAMPIRE); // 4.2% - - mons_place( mon_type, BEH_SLEEP, MHITNOT, true, x, y ); - } - } - } -} // end morgue() - -static void jelly_pit(int level_number, spec_room &sr) -{ - FixedVector< pit_mons_def, MAX_PIT_MONSTERS > pit_list; - const int lordx = sr.x1 + random2(sr.x2 - sr.x1); - const int lordy = sr.y1 + random2(sr.y2 - sr.y1); - - for (int i = 0; i < MAX_PIT_MONSTERS; i++) - { - pit_list[i].type = MONS_PROGRAM_BUG; - pit_list[i].rare = 0; - } - -#if DEBUG_DIAGNOSTICS - mprf( MSGCH_DIAGNOSTICS, "Build: Jelly Pit" ); -#endif - pit_list[0].type = MONS_OOZE; - pit_list[0].rare = 27 - level_number / 5; - - pit_list[1].type = MONS_JELLY; - pit_list[1].rare = 20; - - pit_list[2].type = MONS_BROWN_OOZE; - pit_list[2].rare = 3 + level_number; - - pit_list[3].type = MONS_DEATH_OOZE; - pit_list[3].rare = 2 + (2 * level_number) / 3; - - if (level_number >= 12) - { - pit_list[4].type = MONS_AZURE_JELLY; - pit_list[4].rare = 1 + (level_number - 12) / 3; - } - - if (level_number >= 15) - { - pit_list[5].type = MONS_ACID_BLOB; - pit_list[5].rare = 1 + (level_number - 15) / 4; - } - - fill_monster_pit( sr, pit_list, 90, MONS_PROGRAM_BUG, lordx, lordy ); -} - -static bool place_specific_trap(unsigned char spec_x, unsigned char spec_y, - unsigned char spec_type) -{ - if (spec_type == TRAP_RANDOM) - spec_type = random2(NUM_TRAPS); - - for (int tcount = 0; tcount < MAX_TRAPS; tcount++) - { - if (env.trap[tcount].type == TRAP_UNASSIGNED) - { - env.trap[tcount].type = spec_type; - env.trap[tcount].x = spec_x; - env.trap[tcount].y = spec_y; - grd[spec_x][spec_y] = DNGN_UNDISCOVERED_TRAP; - return true; - } - - if (tcount >= MAX_TRAPS - 1) - return false; - } - - return false; -} // end place_specific_trap() - -void define_zombie( int mid, int ztype, int cs, int power ) -{ - int mons_sec2 = 0; - int zombie_size = 0; - bool ignore_rarity = false; - int test, cls; - - if (power > 27) - power = 27; - - // set size based on zombie class (cs) - switch(cs) - { - case MONS_ZOMBIE_SMALL: - case MONS_SIMULACRUM_SMALL: - case MONS_SKELETON_SMALL: - zombie_size = 1; - break; - - case MONS_ZOMBIE_LARGE: - case MONS_SIMULACRUM_LARGE: - case MONS_SKELETON_LARGE: - zombie_size = 2; - break; - - case MONS_SPECTRAL_THING: - zombie_size = -1; - break; - - default: - // this should NEVER happen. - perror("\ncreate_zombie() got passed incorrect zombie type!\n"); - end(0); - break; - } - - // that is, random creature from which to fashion undead - if (ztype == 250) - { - // how OOD this zombie can be. - int relax = 5; - - // pick an appropriate creature to make a zombie out of, - // levelwise. The old code was generating absolutely - // incredible OOD zombies. - while(true) - { - // this limit can be updated if mons->number goes >8 bits.. - test = random2(182); // not guaranteed to be valid, so.. - cls = mons_species(test); - if (cls == MONS_PROGRAM_BUG) - continue; - - // on certain branches, zombie creation will fail if we use - // the mons_rarity() functions, because (for example) there - // are NO zombifiable "native" abyss creatures. Other branches - // where this is a problem are hell levels and the crypt. - // we have to watch for summoned zombies on other levels, too, - // such as the Temple, HoB, and Slime Pits. - if (you.level_type != LEVEL_DUNGEON - || player_in_hell() - || player_in_branch( BRANCH_HALL_OF_ZOT ) - || player_in_branch( BRANCH_VESTIBULE_OF_HELL ) - || player_in_branch( BRANCH_ECUMENICAL_TEMPLE ) - || player_in_branch( BRANCH_CRYPT ) - || player_in_branch( BRANCH_TOMB ) - || player_in_branch( BRANCH_HALL_OF_BLADES ) - || player_in_branch( BRANCH_SNAKE_PIT ) - || player_in_branch( BRANCH_SLIME_PITS ) - || one_chance_in(1000)) - { - ignore_rarity = true; - } - - // don't make out-of-rarity zombies when we don't have to - if (!ignore_rarity && mons_rarity(cls) == 0) - continue; - - // monster class must be zombifiable - if (!mons_zombie_size(cls)) - continue; - - // if skeleton, monster must have a skeleton - if ((cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE) - && !mons_skeleton(cls)) - { - continue; - } - - // size must match, but you can make a spectral thing out of anything. - if (mons_zombie_size(cls) != zombie_size && zombie_size >= 0) - continue; - - // hack -- non-dungeon zombies are always made out of nastier - // monsters - if (you.level_type != LEVEL_DUNGEON && mons_power(cls) > 8) - break; - - // check for rarity.. and OOD - identical to mons_place() - int level, diff, chance; - - level = mons_level( cls ) - 4; - diff = level - power; - - chance = (ignore_rarity) ? 100 - : mons_rarity(cls) - (diff * diff) / 2; - - if (power > level - relax && power < level + relax - && random2avg(100, 2) <= chance) - { - break; - } - - // every so often, we'll relax the OOD restrictions. Avoids - // infinite loops (if we don't do this, things like creating - // a large skeleton on level 1 may hang the game! - if (one_chance_in(5)) - relax++; - } - - // set type and secondary appropriately - menv[mid].number = cls; - mons_sec2 = cls; - } - else - { - menv[mid].number = mons_species(ztype); - mons_sec2 = menv[mid].number; - } - - menv[mid].type = menv[mid].number; - - define_monster(mid); - - menv[mid].hit_points = hit_points( menv[mid].hit_dice, 6, 5 ); - menv[mid].max_hit_points = menv[mid].hit_points; - - menv[mid].armour_class -= 2; - - if (menv[mid].armour_class < 0) - menv[mid].armour_class = 0; - - menv[mid].evasion -= 5; - - if (menv[mid].evasion < 0) - menv[mid].evasion = 0; - - menv[mid].speed -= 2; - - if (menv[mid].speed < 3) - menv[mid].speed = 3; - - menv[mid].speed_increment = 70; - menv[mid].number = mons_sec2; - - if (cs == MONS_ZOMBIE_SMALL || cs == MONS_ZOMBIE_LARGE) - { - menv[mid].type = ((mons_zombie_size(menv[mid].number) == 2) - ? MONS_ZOMBIE_LARGE : MONS_ZOMBIE_SMALL); - } - else if (cs == MONS_SKELETON_SMALL || cs == MONS_SKELETON_LARGE) - { - menv[mid].hit_points = hit_points( menv[mid].hit_dice, 5, 4 ); - menv[mid].max_hit_points = menv[mid].hit_points; - - menv[mid].armour_class -= 4; - - if (menv[mid].armour_class < 0) - menv[mid].armour_class = 0; - - menv[mid].evasion -= 2; - - if (menv[mid].evasion < 0) - menv[mid].evasion = 0; - - menv[mid].type = ((mons_zombie_size( menv[mid].number ) == 2) - ? MONS_SKELETON_LARGE : MONS_SKELETON_SMALL); - } - else if (cs == MONS_SIMULACRUM_SMALL || cs == MONS_SIMULACRUM_LARGE) - { - // Simulacrum aren't tough, but you can create piles of them. -- bwr - menv[mid].hit_points = hit_points( menv[mid].hit_dice, 1, 4 ); - menv[mid].max_hit_points = menv[mid].hit_points; - menv[mid].type = ((mons_zombie_size( menv[mid].number ) == 2) - ? MONS_SIMULACRUM_LARGE : MONS_SIMULACRUM_SMALL); - } - else if (cs == MONS_SPECTRAL_THING) - { - menv[mid].hit_points = hit_points( menv[mid].hit_dice, 4, 4 ); - menv[mid].max_hit_points = menv[mid].hit_points; - menv[mid].armour_class += 4; - menv[mid].type = MONS_SPECTRAL_THING; - } - - menv[mid].number = mons_sec2; -} // end define_zombie() - -#ifdef USE_RIVERS - -static void build_river( unsigned char river_type ) //mv -{ - int i,j; - int y, width; - - if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) - return; - - // if (one_chance_in(10)) - // build_river(river_type); - - // Made rivers less wide... min width five rivers were too annoying. -- bwr - width = 3 + random2(4); - y = 10 - width + random2avg( GYM-10, 3 ); - - for (i = 5; i < (GXM - 5); i++) - { - if (one_chance_in(3)) y++; - if (one_chance_in(3)) y--; - if (coinflip()) width++; - if (coinflip()) width--; - - if (width < 2) width = 2; - if (width > 6) width = 6; - - for (j = y; j < y+width ; j++) - { - if (j >= 5 && j <= GYM - 5) - { - // Note that vaults might have been created in this area! - // So we'll avoid the silliness of orcs/royal jelly on - // lava and deep water grids. -- bwr - if (!one_chance_in(200) - // && grd[i][j] == DNGN_FLOOR - && mgrd[i][j] == NON_MONSTER - && igrd[i][j] == NON_ITEM) - { - if (width == 2 && river_type == DNGN_DEEP_WATER - && coinflip()) - { - grd[i][j] = DNGN_SHALLOW_WATER; - } - else - grd[i][j] = river_type; - } - } - } - } -} // end build_river() - -static void build_lake(unsigned char lake_type) //mv -{ - int i, j; - int x1, y1, x2, y2; - - if (player_in_branch( BRANCH_CRYPT ) || player_in_branch( BRANCH_TOMB )) - return; - - // if (one_chance_in (10)) - // build_lake(lake_type); - - x1 = 5 + random2(GXM - 30); - y1 = 5 + random2(GYM - 30); - x2 = x1 + 4 + random2(16); - y2 = y1 + 8 + random2(12); - // mpr("lake"); - - for (j = y1; j < y2; j++) - { - if (coinflip()) x1 += random2(3); - if (coinflip()) x1 -= random2(3); - if (coinflip()) x2 += random2(3); - if (coinflip()) x2 -= random2(3); - - // mv: this does much more worse effects - // if (coinflip()) x1 = x1 -2 + random2(5); - // if (coinflip()) x2 = x2 -2 + random2(5); - - if ((j-y1) < ((y2-y1) / 2)) - { - x2 += random2(3); - x1 -= random2(3); - } - else - { - x2 -= random2(3); - x1 += random2(3); - } - - for (i = x1; i < x2 ; i++) - { - if ((j >= 5 && j <= GYM - 5) && (i >= 5 && i <= GXM - 5)) - { - // Note that vaults might have been created in this area! - // So we'll avoid the silliness of monsters and items - // on lava and deep water grids. -- bwr - if (!one_chance_in(200) - // && grd[i][j] == DNGN_FLOOR - && mgrd[i][j] == NON_MONSTER - && igrd[i][j] == NON_ITEM) - { - grd[i][j] = lake_type; - } - } - } - } -} // end lake() - -#endif // USE_RIVERS |