summaryrefslogtreecommitdiffstats
path: root/stone_soup/crawl-ref/source/dungeon.cc
diff options
context:
space:
mode:
Diffstat (limited to 'stone_soup/crawl-ref/source/dungeon.cc')
-rw-r--r--stone_soup/crawl-ref/source/dungeon.cc8641
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