diff options
Diffstat (limited to 'stone_soup/crawl-ref/source/monplace.cc')
-rw-r--r-- | stone_soup/crawl-ref/source/monplace.cc | 1405 |
1 files changed, 0 insertions, 1405 deletions
diff --git a/stone_soup/crawl-ref/source/monplace.cc b/stone_soup/crawl-ref/source/monplace.cc deleted file mode 100644 index 0d1013e3f2..0000000000 --- a/stone_soup/crawl-ref/source/monplace.cc +++ /dev/null @@ -1,1405 +0,0 @@ -/* - * File: monplace.cc - * Summary: Functions used when placing monsters in the dungeon. - * Written by: Linley Henzell - * - * Change History (most recent first): - * - * <1> -/--/-- LRH Created - */ - -#include "AppHdr.h" -#include "monplace.h" - -#include "externs.h" -#include "dungeon.h" -#include "monstuff.h" -#include "mon-pick.h" -#include "mon-util.h" -#include "misc.h" -#include "player.h" -#include "stuff.h" -#include "spells4.h" - -// NEW place_monster -- note that power should be set to: -// 51 for abyss -// 52 for pandemonium -// x otherwise - -// proximity is the same as for mons_place: -// 0 is no restrictions -// 1 attempts to place near player -// 2 attempts to avoid player LOS - -#define BIG_BAND 20 - -static int band_member(int band, int power); -static int choose_band( int mon_type, int power, int &band_size ); -static int place_monster_aux(int mon_type, char behaviour, int target, - int px, int py, int power, int extra, bool first_band_member, - int dur = 0); - -bool place_monster(int &id, int mon_type, int power, char behaviour, - int target, bool summoned, int px, int py, bool allow_bands, - int proximity, int extra, int dur) -{ - int band_size = 0; - int band_monsters[BIG_BAND]; // band monster types - int lev_mons = power; // final 'power' - int count; - int i; - - // set initial id to -1 (unsuccessful create) - id = -1; - - // (1) early out (summoned to occupied grid) - if (summoned && mgrd[px][py] != NON_MONSTER) - return (false); - - // (2) take care of random monsters - if (mon_type == RANDOM_MONSTER - && player_in_branch( BRANCH_HALL_OF_BLADES )) - { - mon_type = MONS_DANCING_WEAPON; - } - - if (mon_type == RANDOM_MONSTER) - { - if (player_in_branch( BRANCH_MAIN_DUNGEON ) - && lev_mons != 51 && one_chance_in(4)) - { - lev_mons = random2(power); - } - - if (player_in_branch( BRANCH_MAIN_DUNGEON ) && lev_mons < 28) - { - // potentially nasty surprise, but very rare - if (one_chance_in(5000)) - lev_mons = random2(27); - - // slightly out of depth monsters are more common: - if (one_chance_in(50)) - lev_mons += random2(6); - - if (lev_mons > 27) - lev_mons = 27; - } - - /* Abyss or Pandemonium. Almost never called from Pan; - probably only if a rand demon gets summon anything spell */ - if (lev_mons == 51 - || you.level_type == LEVEL_PANDEMONIUM - || you.level_type == LEVEL_ABYSS) - { - do - { - count = 0; - - do - { - // was: random2(400) {dlb} - mon_type = random2(NUM_MONSTERS); - count++; - } - while (mons_abyss(mon_type) == 0 && count < 2000); - - if (count == 2000) - return (false); - } - while (random2avg(100, 2) > mons_rare_abyss(mon_type) - && !one_chance_in(100)); - } - else - { - int level, diff, chance; - - if (lev_mons > 30) - lev_mons = 30; - - for (i = 0; i < 10000; i++) - { - count = 0; - - do - { - mon_type = random2(NUM_MONSTERS); - count++; - } - while (mons_rarity(mon_type) == 0 && count < 2000); - - if (count == 2000) - return (false); - - level = mons_level( mon_type ); - diff = level - lev_mons; - chance = mons_rarity( mon_type ) - (diff * diff); - - if ((lev_mons >= level - 5 && lev_mons <= level + 5) - && random2avg(100, 2) <= chance) - { - break; - } - } - - if (i == 10000) - return (false); - } - } - - // (3) decide on banding (good lord!) - band_size = 1; - band_monsters[0] = mon_type; - - if (allow_bands) - { - int band = choose_band(mon_type, power, band_size); - band_size ++; - - for (i = 1; i < band_size; i++) - band_monsters[i] = band_member( band, power ); - } - - // Monsters that can't move shouldn't be taking the stairs -- bwr - if (proximity == PROX_NEAR_STAIRS && mons_speed( mon_type ) == 0) - proximity = PROX_AWAY_FROM_PLAYER; - - // (4) for first monster, choose location. This is pretty intensive. - bool proxOK; - bool close_to_player; - - // player shoved out of the way? - bool shoved = false; - unsigned char stair_gfx = 0; - int pval = 0; - - if (!summoned) - { - int tries = 0; - // try to pick px, py that is - // a) not occupied - // b) compatible - // c) in the 'correct' proximity to the player - unsigned char grid_wanted = monster_habitat(mon_type); - while(true) - { - tries ++; - // give up on stair placement? - if (proximity == PROX_NEAR_STAIRS) - { - if (tries > 320) - { - proximity = PROX_AWAY_FROM_PLAYER; - tries = 0; - } - } - else if (tries > 60) - return (false); - - px = 5 + random2(GXM - 10); - py = 5 + random2(GYM - 10); - - // occupied? - if (mgrd[px][py] != NON_MONSTER - || (px == you.x_pos && py == you.y_pos)) - { - continue; - } - - // compatible - floor? - if (grid_wanted == DNGN_FLOOR && grd[px][py] < DNGN_FLOOR) - continue; - - // compatible - others (must match, except for deep water monsters - // generated in shallow water) - if ((grid_wanted != DNGN_FLOOR && grd[px][py] != grid_wanted) - && (grid_wanted != DNGN_DEEP_WATER || grd[px][py] != DNGN_SHALLOW_WATER)) - { - continue; - } - - // don't generate monsters on top of teleport traps - // (how did they get there?) - int trap = trap_at_xy(px, py); - if (trap >= 0) - { - if (env.trap[trap].type == TRAP_TELEPORT) - continue; - } - - // check proximity to player - proxOK = true; - - switch (proximity) - { - case PROX_ANYWHERE: - if (grid_distance( you.x_pos, you.y_pos, px, py ) < 2 + random2(3)) - { - proxOK = false; - } - break; - - case PROX_CLOSE_TO_PLAYER: - case PROX_AWAY_FROM_PLAYER: - close_to_player = (distance(you.x_pos, you.y_pos, px, py) < 64); - - if ((proximity == PROX_CLOSE_TO_PLAYER && !close_to_player) - || (proximity == PROX_AWAY_FROM_PLAYER && close_to_player)) - { - proxOK = false; - } - break; - - case PROX_NEAR_STAIRS: - pval = near_stairs(px, py, 1, stair_gfx); - if (pval == 2) - { - // 0 speed monsters can't shove player out of their way. - if (mons_speed(mon_type) == 0) - { - proxOK = false; - break; - } - // swap the monster and the player spots, unless the - // monster was generated in lava or deep water. - if (grd[px][py] == DNGN_LAVA || grd[px][py] == DNGN_DEEP_WATER) - { - proxOK = false; - break; - } - shoved = true; - int tpx = px; - int tpy = py; - px = you.x_pos; - py = you.y_pos; - you.x_pos = tpx; - you.y_pos = tpy; - } - - proxOK = (pval > 0); - break; - default: - break; - } - - if (!proxOK) - continue; - - // cool.. passes all tests - break; - } // end while.. place first monster - } - - id = place_monster_aux( mon_type, behaviour, target, px, py, lev_mons, - extra, true ); - - // now, forget about banding if the first placement failed, or there's too - // many monsters already, or we successfully placed by stairs - if (id < 0 || id+30 > MAX_MONSTERS) - return false; - - // message to player from stairwell/gate appearance? - if (see_grid(px, py) && proximity == PROX_NEAR_STAIRS) - { - info[0] = '\0'; - - if (player_monster_visible( &menv[id] )) - strcpy(info, ptr_monam( &menv[id], DESC_CAP_A )); - else if (shoved) - strcpy(info, "Something"); - - if (shoved) - { - strcat(info, " shoves you out of the "); - strcat(info, (stair_gfx == '>' || stair_gfx == '<') ? "stairwell!" - : "gateway!"); - mpr(info); - } - else if (info[0] != '\0') - { - strcat(info, (stair_gfx == '>') ? " comes up the stairs." : - (stair_gfx == '<') ? " comes down the stairs." - : " comes through the gate."); - mpr(info); - } - - // special case: must update the view for monsters created in player LOS - viewwindow(1, false); - } - - // monsters placed by stairs don't bring the whole band up/down/through - // with them - if (proximity == PROX_NEAR_STAIRS) - return (true); - - // (5) for each band monster, loop call to place_monster_aux(). - for(i = 1; i < band_size; i++) - { - place_monster_aux( band_monsters[i], behaviour, target, px, py, - lev_mons, extra, false, dur ); - } - - // placement of first monster, at least, was a success. - return (true); -} - -static int place_monster_aux( int mon_type, char behaviour, int target, - int px, int py, int power, int extra, - bool first_band_member, int dur ) -{ - int id, i; - char grid_wanted; - int fx=0, fy=0; // final x,y - - // gotta be able to pick an ID - for (id = 0; id < MAX_MONSTERS; id++) - { - if (menv[id].type == -1) - break; - } - - if (id == MAX_MONSTERS) - return -1; - - // scrap monster inventory - for (i = 0; i < NUM_MONSTER_SLOTS; i++) - menv[id].inv[i] = NON_ITEM; - - // scrap monster enchantments - for (i = 0; i < NUM_MON_ENCHANTS; i++) - menv[id].enchantment[i] = ENCH_NONE; - - // setup habitat and placement - if (first_band_member) - { - fx = px; - fy = py; - } - else - { - grid_wanted = monster_habitat(mon_type); - - // we'll try 1000 times for a good spot - for (i = 0; i < 1000; i++) - { - fx = px + random2(7) - 3; - fy = py + random2(7) - 3; - - // occupied? - if (mgrd[fx][fy] != NON_MONSTER) - continue; - - // compatible - floor? - if (grid_wanted == DNGN_FLOOR && grd[fx][fy] < DNGN_FLOOR) - continue; - - // compatible - others (must match, except for deep water monsters - // generated in shallow water) - if ((grid_wanted != DNGN_FLOOR && grd[fx][fy] != grid_wanted) - && (grid_wanted != DNGN_DEEP_WATER || grd[fx][fy] != DNGN_SHALLOW_WATER)) - continue; - - // don't generate monsters on top of teleport traps - // (how do they get there?) - int trap = trap_at_xy(fx, fy); - if (trap >= 0) - if (env.trap[trap].type == TRAP_TELEPORT) - continue; - - // cool.. passes all tests - break; - } - - // did we really try 1000 times? - if (i == 1000) - return (-1); - } - - // now, actually create the monster (wheeee!) - menv[id].type = mon_type; - menv[id].number = 250; - - menv[id].x = fx; - menv[id].y = fy; - - // link monster into monster grid - mgrd[fx][fy] = id; - - // generate a brand shiny new monster, or zombie - if (mon_type == MONS_ZOMBIE_SMALL - || mon_type == MONS_ZOMBIE_LARGE - || mon_type == MONS_SIMULACRUM_SMALL - || mon_type == MONS_SIMULACRUM_LARGE - || mon_type == MONS_SKELETON_SMALL - || mon_type == MONS_SKELETON_LARGE - || mon_type == MONS_SPECTRAL_THING) - { - define_zombie( id, extra, mon_type, power ); - } - else - { - define_monster(id); - } - - // The return of Boris is now handled in monster_die()... - // not setting this for Boris here allows for multiple Borises - // in the dungeon at the same time. -- bwr - if (mon_type >= MONS_TERENCE && mon_type <= MONS_BORIS) - you.unique_creatures[mon_type - 280] = 1; - - if (extra != 250) - menv[id].number = extra; - - if (mons_class_flag(mon_type, M_INVIS)) - mons_add_ench(&menv[id], ENCH_INVIS); - - if (mons_class_flag(mon_type, M_CONFUSED)) - mons_add_ench(&menv[id], ENCH_CONFUSION); - - if (mon_type == MONS_SHAPESHIFTER) - mons_add_ench(&menv[id], ENCH_SHAPESHIFTER); - - if (mon_type == MONS_GLOWING_SHAPESHIFTER) - mons_add_ench(&menv[id], ENCH_GLOWING_SHAPESHIFTER); - - if (mon_type == MONS_GIANT_BAT || mon_type == MONS_UNSEEN_HORROR - || mon_type == MONS_GIANT_BLOWFLY) - { - menv[id].flags |= MF_BATTY; - } - - if ((mon_type == MONS_BIG_FISH - || mon_type == MONS_GIANT_GOLDFISH - || mon_type == MONS_ELECTRICAL_EEL - || mon_type == MONS_JELLYFISH - || mon_type == MONS_WATER_ELEMENTAL - || mon_type == MONS_SWAMP_WORM) - && grd[fx][fy] == DNGN_DEEP_WATER - && !one_chance_in(5)) - { - mons_add_ench( &menv[id], ENCH_SUBMERGED ); - } - - if ((mon_type == MONS_LAVA_WORM - || mon_type == MONS_LAVA_FISH - || mon_type == MONS_LAVA_SNAKE - || mon_type == MONS_SALAMANDER) - && grd[fx][fy] == DNGN_LAVA - && !one_chance_in(5)) - { - mons_add_ench( &menv[id], ENCH_SUBMERGED ); - } - - menv[id].flags |= MF_JUST_SUMMONED; - - if (mon_type == MONS_DANCING_WEAPON && extra != 1) // ie not from spell - { - give_item( id, power ); - - if (menv[id].inv[MSLOT_WEAPON] != NON_ITEM) - menv[id].number = mitm[ menv[id].inv[MSLOT_WEAPON] ].colour; - } - else if (mons_itemuse(mon_type) >= MONUSE_STARTING_EQUIPMENT) - { - give_item( id, power ); - - // Give these monsters a second weapon -- bwr - if (mon_type == MONS_TWO_HEADED_OGRE || mon_type == MONS_ETTIN) - { - give_item( id, power ); - } - } - - - // give manticores 8 to 16 spike volleys. - // they're not spellcasters so this doesn't screw anything up. - if (mon_type == MONS_MANTICORE) - menv[id].number = 8 + random2(9); - - // set attitude, behaviour and target - menv[id].attitude = ATT_HOSTILE; - menv[id].behaviour = behaviour; - menv[id].foe_memory = 0; - - // setting attitude will always make the - // monster wander.. if you want sleeping - // hostiles, use BEH_SLEEP since the default - // attitude is hostile. - if (behaviour > NUM_BEHAVIOURS) - { - if (behaviour == BEH_FRIENDLY || behaviour == BEH_GOD_GIFT) - menv[id].attitude = ATT_FRIENDLY; - - menv[id].behaviour = BEH_WANDER; - } - - // dur should always be ENCH_ABJ_xx - if (dur >= ENCH_ABJ_I && dur <= ENCH_ABJ_VI) - mons_add_ench(&menv[id], dur ); - - menv[id].foe = target; - - return (id); -} // end place_monster_aux() - - -static int choose_band( int mon_type, int power, int &band_size ) -{ - // init - band_size = 0; - int band = BAND_NO_BAND; - - switch (mon_type) - { - case MONS_ORC: - if (coinflip()) - break; - // intentional fall-through {dlb} - case MONS_ORC_WARRIOR: - band = BAND_ORCS; // orcs - band_size = 2 + random2(3); - break; - - case MONS_BIG_KOBOLD: - if (power > 3) - { - band = BAND_KOBOLDS; - band_size = 2 + random2(6); - } - break; - - case MONS_ORC_WARLORD: - band_size = 5 + random2(5); // warlords have large bands - // intentional fall through - case MONS_ORC_KNIGHT: - band = BAND_ORC_KNIGHT; // orcs + knight - band_size += 3 + random2(4); - break; - - case MONS_KILLER_BEE: - band = BAND_KILLER_BEES; // killer bees - band_size = 2 + random2(4); - break; - - case MONS_FLYING_SKULL: - band = BAND_FLYING_SKULLS; // flying skulls - band_size = 2 + random2(4); - break; - case MONS_SLIME_CREATURE: - band = BAND_SLIME_CREATURES; // slime creatures - band_size = 2 + random2(4); - break; - case MONS_YAK: - band = BAND_YAKS; // yaks - band_size = 2 + random2(4); - break; - case MONS_UGLY_THING: - band = BAND_UGLY_THINGS; // ugly things - band_size = 2 + random2(4); - break; - case MONS_HELL_HOUND: - band = BAND_HELL_HOUNDS; // hell hound - band_size = 2 + random2(3); - break; - case MONS_JACKAL: - band = BAND_JACKALS; // jackal - band_size = 1 + random2(3); - break; - case MONS_HELL_KNIGHT: - case MONS_MARGERY: - band = BAND_HELL_KNIGHTS; // hell knight - band_size = 4 + random2(4); - break; - case MONS_JOSEPHINE: - case MONS_NECROMANCER: - case MONS_VAMPIRE_MAGE: - band = BAND_NECROMANCER; // necromancer - band_size = 4 + random2(4); - break; - case MONS_ORC_HIGH_PRIEST: - band = BAND_ORC_HIGH_PRIEST; // orc high priest - band_size = 4 + random2(4); - break; - case MONS_GNOLL: - band = BAND_GNOLLS; // gnoll - band_size = ((coinflip())? 3 : 2); - break; - case MONS_BUMBLEBEE: - band = BAND_BUMBLEBEES; // bumble bees - band_size = 2 + random2(4); - break; - case MONS_CENTAUR: - case MONS_CENTAUR_WARRIOR: - if (power > 9 && one_chance_in(3)) - { - band = BAND_CENTAURS; // centaurs - band_size = 2 + random2(4); - } - break; - - case MONS_YAKTAUR: - case MONS_YAKTAUR_CAPTAIN: - if (coinflip()) - { - band = BAND_YAKTAURS; // yaktaurs - band_size = 2 + random2(3); - } - break; - - case MONS_DEATH_YAK: - band = BAND_DEATH_YAKS; // death yaks - band_size = 2 + random2(4); - break; - case MONS_INSUBSTANTIAL_WISP: - band = BAND_INSUBSTANTIAL_WISPS; // wisps - band_size = 4 + random2(5); - break; - case MONS_OGRE_MAGE: - band = BAND_OGRE_MAGE; // ogre mage - band_size = 4 + random2(4); - break; - case MONS_BALRUG: - band = BAND_BALRUG; // RED gr demon - band_size = 2 + random2(3); - break; - case MONS_CACODEMON: - band = BAND_CACODEMON; // BROWN gr demon - band_size = 1 + random2(3); - break; - - case MONS_EXECUTIONER: - if (coinflip()) - { - band = BAND_EXECUTIONER; // DARKGREY gr demon - band_size = 1 + random2(3); - } - break; - - case MONS_HELLWING: - if (coinflip()) - { - band = BAND_HELLWING; // LIGHTGREY gr demon - band_size = 1 + random2(4); - } - break; - - case MONS_DEEP_ELF_FIGHTER: - if (coinflip()) - { - band = BAND_DEEP_ELF_FIGHTER; // deep elf warrior - band_size = 3 + random2(4); - } - break; - - case MONS_DEEP_ELF_KNIGHT: - if (coinflip()) - { - band = BAND_DEEP_ELF_KNIGHT; // deep elf knight - band_size = 3 + random2(4); - } - break; - - case MONS_DEEP_ELF_HIGH_PRIEST: - if (coinflip()) - { - band = BAND_DEEP_ELF_HIGH_PRIEST; // deep elf high priest - band_size = 3 + random2(4); - } - break; - - case MONS_KOBOLD_DEMONOLOGIST: - if (coinflip()) - { - band = BAND_KOBOLD_DEMONOLOGIST; // kobold demonologist - band_size = 3 + random2(6); - } - break; - - case MONS_NAGA_MAGE: - case MONS_NAGA_WARRIOR: - band = BAND_NAGAS; // Nagas - band_size = 3 + random2(4); - break; - case MONS_WAR_DOG: - band = BAND_WAR_DOGS; // war dogs - band_size = 2 + random2(4); - break; - case MONS_GREY_RAT: - band = BAND_GREY_RATS; // grey rats - band_size = 4 + random2(6); - break; - case MONS_GREEN_RAT: - band = BAND_GREEN_RATS; // green rats - band_size = 4 + random2(6); - break; - case MONS_ORANGE_RAT: - band = BAND_ORANGE_RATS; // orange rats - band_size = 3 + random2(4); - break; - case MONS_SHEEP: - band = BAND_SHEEP; // sheep - band_size = 3 + random2(5); - break; - case MONS_GHOUL: - band = BAND_GHOULS; // ghoul - band_size = 2 + random2(3); - break; - case MONS_HOG: - band = BAND_HOGS; // hog - band_size = 1 + random2(3); - break; - case MONS_GIANT_MOSQUITO: - band = BAND_GIANT_MOSQUITOES; // mosquito - band_size = 1 + random2(3); - break; - case MONS_DEEP_TROLL: - band = BAND_DEEP_TROLLS; // deep troll - band_size = 3 + random2(3); - break; - case MONS_HELL_HOG: - band = BAND_HELL_HOGS; // hell-hog - band_size = 1 + random2(3); - break; - case MONS_BOGGART: - band = BAND_BOGGARTS; // boggart - band_size = 2 + random2(3); - break; - case MONS_BLINK_FROG: - band = BAND_BLINK_FROGS; // blink frog - band_size = 2 + random2(3); - break; - case MONS_SKELETAL_WARRIOR: - band = BAND_SKELETAL_WARRIORS; // skeletal warrior - band_size = 2 + random2(3); - break; - // Journey -- Added Draconian Packs - case MONS_WHITE_DRACONIAN: - case MONS_RED_DRACONIAN: - case MONS_PURPLE_DRACONIAN: - case MONS_MOTTLED_DRACONIAN: - case MONS_YELLOW_DRACONIAN: - case MONS_BLACK_DRACONIAN: - case MONS_GREEN_DRACONIAN: - case MONS_PALE_DRACONIAN: - if (power > 18 && one_chance_in(3)) - { - band = BAND_DRACONIAN; - band_size = 2 + random2(3); - } - break; - case MONS_DRACONIAN_CALLER: - case MONS_DRACONIAN_MONK: - case MONS_DRACONIAN_SCORCHER: - case MONS_DRACONIAN_KNIGHT: - case MONS_DRACONIAN_ANNIHILATOR: - case MONS_DRACONIAN_ZEALOT: - case MONS_DRACONIAN_SHIFTER: - if (power > 20) - { - band = BAND_DRACONIAN; - band_size = 3 + random2(4); - } - break; - } // end switch - - if (band != BAND_NO_BAND && band_size == 0) - band = BAND_NO_BAND; - - if (band_size >= BIG_BAND) - band_size = BIG_BAND-1; - - return (band); -} - -static int band_member(int band, int power) -{ - int mon_type = -1; - int temp_rand; - - if (band == BAND_NO_BAND) - return -1; - - switch (band) - { - case BAND_KOBOLDS: - mon_type = MONS_KOBOLD; - break; - - case BAND_ORC_KNIGHT: - case BAND_ORC_HIGH_PRIEST: - temp_rand = random2(30); - mon_type = ((temp_rand > 17) ? MONS_ORC : // 12 in 30 - (temp_rand > 8) ? MONS_ORC_WARRIOR : // 9 in 30 - (temp_rand > 6) ? MONS_WARG : // 2 in 30 - (temp_rand > 4) ? MONS_ORC_WIZARD : // 2 in 30 - (temp_rand > 2) ? MONS_ORC_PRIEST : // 2 in 30 - (temp_rand > 1) ? MONS_OGRE : // 1 in 30 - (temp_rand > 0) ? MONS_TROLL // 1 in 30 - : MONS_ORC_SORCERER); // 1 in 30 - break; - - case BAND_KILLER_BEES: - mon_type = MONS_KILLER_BEE; - break; - - case BAND_FLYING_SKULLS: - mon_type = MONS_FLYING_SKULL; - break; - - case BAND_SLIME_CREATURES: - mon_type = MONS_SLIME_CREATURE; - break; - - case BAND_YAKS: - mon_type = MONS_YAK; - break; - - case BAND_UGLY_THINGS: - mon_type = ((power > 21 && one_chance_in(4)) ? - MONS_VERY_UGLY_THING : MONS_UGLY_THING); - break; - - case BAND_HELL_HOUNDS: - mon_type = MONS_HELL_HOUND; - break; - - case BAND_JACKALS: - mon_type = MONS_JACKAL; - break; - - case BAND_GNOLLS: - mon_type = MONS_GNOLL; - break; - - case BAND_BUMBLEBEES: - mon_type = MONS_BUMBLEBEE; - break; - - case BAND_CENTAURS: - mon_type = MONS_CENTAUR; - break; - - case BAND_YAKTAURS: - mon_type = MONS_YAKTAUR; - break; - - case BAND_INSUBSTANTIAL_WISPS: - mon_type = MONS_INSUBSTANTIAL_WISP; - break; - - case BAND_DEATH_YAKS: - mon_type = MONS_DEATH_YAK; - break; - - case BAND_NECROMANCER: // necromancer - temp_rand = random2(13); - mon_type = ((temp_rand > 9) ? MONS_ZOMBIE_SMALL : // 3 in 13 - (temp_rand > 6) ? MONS_ZOMBIE_LARGE : // 3 in 13 - (temp_rand > 3) ? MONS_SKELETON_SMALL : // 3 in 13 - (temp_rand > 0) ? MONS_SKELETON_LARGE // 3 in 13 - : MONS_NECROPHAGE); // 1 in 13 - break; - - case BAND_BALRUG: - mon_type = (coinflip()? MONS_NEQOXEC : MONS_ORANGE_DEMON); - break; - - case BAND_CACODEMON: - mon_type = MONS_LEMURE; - break; - - case BAND_EXECUTIONER: - mon_type = (coinflip() ? MONS_ABOMINATION_SMALL : MONS_ABOMINATION_LARGE); - break; - - case BAND_HELLWING: - mon_type = (coinflip() ? MONS_HELLWING : MONS_SMOKE_DEMON); - break; - - case BAND_DEEP_ELF_FIGHTER: // deep elf fighter - temp_rand = random2(11); - mon_type = ((temp_rand > 4) ? MONS_DEEP_ELF_SOLDIER : // 6 in 11 - (temp_rand == 4) ? MONS_DEEP_ELF_FIGHTER : // 1 in 11 - (temp_rand == 3) ? MONS_DEEP_ELF_KNIGHT : // 1 in 11 - (temp_rand == 2) ? MONS_DEEP_ELF_CONJURER :// 1 in 11 - (temp_rand == 1) ? MONS_DEEP_ELF_MAGE // 1 in 11 - : MONS_DEEP_ELF_PRIEST); // 1 in 11 - break; - - case BAND_ORCS: - mon_type = MONS_ORC; - if (one_chance_in(5)) - mon_type = MONS_ORC_WIZARD; - if (one_chance_in(7)) - mon_type = MONS_ORC_PRIEST; - break; - - case BAND_HELL_KNIGHTS: - mon_type = MONS_HELL_KNIGHT; - if (one_chance_in(4)) - mon_type = MONS_NECROMANCER; - break; - - //case 12 is orc high priest - - case BAND_OGRE_MAGE: - mon_type = MONS_OGRE; - if (one_chance_in(3)) - mon_type = MONS_TWO_HEADED_OGRE; - break; // ogre mage - - // comment does not match value (30, TWO_HEADED_OGRE) prior to - // enum replacement [!!!] 14jan2000 {dlb} - - case BAND_DEEP_ELF_KNIGHT: // deep elf knight - temp_rand = random2(208); - mon_type = - ((temp_rand > 159) ? MONS_DEEP_ELF_SOLDIER : // 23.08% - (temp_rand > 111) ? MONS_DEEP_ELF_FIGHTER : // 23.08% - (temp_rand > 79) ? MONS_DEEP_ELF_KNIGHT : // 15.38% - (temp_rand > 51) ? MONS_DEEP_ELF_MAGE : // 13.46% - (temp_rand > 35) ? MONS_DEEP_ELF_PRIEST : // 7.69% - (temp_rand > 19) ? MONS_DEEP_ELF_CONJURER : // 7.69% - (temp_rand > 3) ? MONS_DEEP_ELF_SUMMONER : // 7.69% - (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 0.48% - (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 0.48% - (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 0.48% - : MONS_DEEP_ELF_DEATH_MAGE); // 0.48% - break; - - case BAND_DEEP_ELF_HIGH_PRIEST: // deep elf high priest - temp_rand = random2(16); - mon_type = - ((temp_rand > 12) ? MONS_DEEP_ELF_SOLDIER : // 3 in 16 - (temp_rand > 9) ? MONS_DEEP_ELF_FIGHTER : // 3 in 16 - (temp_rand > 6) ? MONS_DEEP_ELF_PRIEST : // 3 in 16 - (temp_rand == 6) ? MONS_DEEP_ELF_MAGE : // 1 in 16 - (temp_rand == 5) ? MONS_DEEP_ELF_SUMMONER : // 1 in 16 - (temp_rand == 4) ? MONS_DEEP_ELF_CONJURER : // 1 in 16 - (temp_rand == 3) ? MONS_DEEP_ELF_DEMONOLOGIST :// 1 in 16 - (temp_rand == 2) ? MONS_DEEP_ELF_ANNIHILATOR : // 1 in 16 - (temp_rand == 1) ? MONS_DEEP_ELF_SORCERER // 1 in 16 - : MONS_DEEP_ELF_DEATH_MAGE); // 1 in 16 - break; - - case BAND_KOBOLD_DEMONOLOGIST: - temp_rand = random2(13); - mon_type = ((temp_rand > 4) ? MONS_KOBOLD : // 8 in 13 - (temp_rand > 0) ? MONS_BIG_KOBOLD // 4 in 13 - : MONS_KOBOLD_DEMONOLOGIST);// 1 in 13 - break; - - case BAND_NAGAS: - mon_type = MONS_NAGA; - break; - case BAND_WAR_DOGS: - mon_type = MONS_WAR_DOG; - break; - case BAND_GREY_RATS: - mon_type = MONS_GREY_RAT; - break; - case BAND_GREEN_RATS: - mon_type = MONS_GREEN_RAT; - break; - case BAND_ORANGE_RATS: - mon_type = MONS_ORANGE_RAT; - break; - case BAND_SHEEP: - mon_type = MONS_SHEEP; - break; - case BAND_GHOULS: - mon_type = (coinflip() ? MONS_GHOUL : MONS_NECROPHAGE); - break; - case BAND_DEEP_TROLLS: - mon_type = MONS_DEEP_TROLL; - break; - case BAND_HOGS: - mon_type = MONS_HOG; - break; - case BAND_HELL_HOGS: - mon_type = MONS_HELL_HOG; - break; - case BAND_GIANT_MOSQUITOES: - mon_type = MONS_GIANT_MOSQUITO; - break; - case BAND_BOGGARTS: - mon_type = MONS_BOGGART; - break; - case BAND_BLINK_FROGS: - mon_type = MONS_BLINK_FROG; - break; - case BAND_SKELETAL_WARRIORS: - mon_type = MONS_SKELETAL_WARRIOR; - break; - case BAND_DRACONIAN: - { - const int temp_rand = random2( (power < 24) ? 24 : 37 ); - mon_type = - ((temp_rand > 35) ? MONS_DRACONIAN_CALLER : // 1 in 34 - (temp_rand > 33) ? MONS_DRACONIAN_KNIGHT : // 2 in 34 - (temp_rand > 31) ? MONS_DRACONIAN_MONK : // 2 in 34 - (temp_rand > 29) ? MONS_DRACONIAN_SHIFTER : // 2 in 34 - (temp_rand > 27) ? MONS_DRACONIAN_ANNIHILATOR :// 2 in 34 - (temp_rand > 25) ? MONS_DRACONIAN_SCORCHER : // 2 in 34 - (temp_rand > 23) ? MONS_DRACONIAN_ZEALOT : // 2 in 34 - (temp_rand > 20) ? MONS_YELLOW_DRACONIAN : // 3 in 34 - (temp_rand > 17) ? MONS_GREEN_DRACONIAN : // 3 in 34 - (temp_rand > 14) ? MONS_BLACK_DRACONIAN : // 3 in 34 - (temp_rand > 11) ? MONS_WHITE_DRACONIAN : // 3 in 34 - (temp_rand > 8) ? MONS_PALE_DRACONIAN : // 3 in 34 - (temp_rand > 5) ? MONS_PURPLE_DRACONIAN : // 3 in 34 - (temp_rand > 2) ? MONS_MOTTLED_DRACONIAN : // 3 in 34 - MONS_RED_DRACONIAN ); // 3 in 34 - break; - } - } - - return (mon_type); -} - -// PUBLIC FUNCTION -- mons_place(). - -int mons_place( int mon_type, char behaviour, int target, bool summoned, - int px, int py, int level_type, int proximity, int extra, - int dur ) -{ - int mon_count = 0; - int temp_rand; // probabilty determination {dlb} - bool permit_bands = false; - - for (int il = 0; il < MAX_MONSTERS; il++) - { - if (menv[il].type != -1) - mon_count++; - } - - if (mon_type == WANDERING_MONSTER) - { - if (mon_count > 150) - return (-1); - - mon_type = RANDOM_MONSTER; - } - - // all monsters have been assigned? {dlb} - if (mon_count > MAX_MONSTERS - 2) - return (-1); - - // this gives a slight challenge to the player as they ascend the - // dungeon with the Orb - if (you.char_direction == DIR_ASCENDING && mon_type == RANDOM_MONSTER - && you.level_type == LEVEL_DUNGEON) - { - temp_rand = random2(276); - - mon_type = ((temp_rand > 184) ? MONS_WHITE_IMP + random2(15) : // 33.33% - (temp_rand > 104) ? MONS_HELLION + random2(10) : // 28.99% - (temp_rand > 78) ? MONS_HELL_HOUND : // 9.06% - (temp_rand > 54) ? MONS_ABOMINATION_LARGE : // 8.70% - (temp_rand > 33) ? MONS_ABOMINATION_SMALL : // 7.61% - (temp_rand > 13) ? MONS_RED_DEVIL // 7.25% - : MONS_PIT_FIEND); // 5.07% - } - - if (mon_type == RANDOM_MONSTER || level_type == LEVEL_PANDEMONIUM) - permit_bands = true; - - int mid = -1; - - // translate level_type - int power; - - switch (level_type) - { - case LEVEL_PANDEMONIUM: - power = 52; // sigh.. - break; - case LEVEL_ABYSS: - power = 51; - break; - case LEVEL_DUNGEON: // intentional fallthrough - default: - power = you.your_level; - break; - } - - if (place_monster( mid, mon_type, power, behaviour, target, summoned, - px, py, permit_bands, proximity, extra, dur ) == false) - { - return (-1); - } - - if (mid != -1) - { - struct monsters *const creation = &menv[mid]; - - // look at special cases: CHARMED, FRIENDLY, HOSTILE, GOD_GIFT - // alert summoned being to player's presence - if (behaviour > NUM_BEHAVIOURS) - { - if (behaviour == BEH_FRIENDLY || behaviour == BEH_GOD_GIFT) - creation->flags |= MF_CREATED_FRIENDLY; - - if (behaviour == BEH_GOD_GIFT) - creation->flags |= MF_GOD_GIFT; - - if (behaviour == BEH_CHARMED) - { - creation->attitude = ATT_HOSTILE; - mons_add_ench(creation, ENCH_CHARM); - } - - // make summoned being aware of player's presence - behaviour_event(creation, ME_ALERT, MHITYOU); - } - } - - return (mid); -} // end mons_place() - - -int create_monster( int cls, int dur, int beha, int cr_x, int cr_y, - int hitting, int zsec ) -{ - int summd = -1; - FixedVector < char, 2 > empty; - - unsigned char spcw = ((cls == RANDOM_MONSTER) ? DNGN_FLOOR - : monster_habitat( cls )); - - empty[0] = 0; - empty[1] = 0; - - // Might be better if we chose a space and tried to match the monster - // to it in the case of RANDOM_MONSTER, that way if the target square - // is surrounded by water of lava this function would work. -- bwr - if (empty_surrounds( cr_x, cr_y, spcw, true, empty )) - { - summd = mons_place( cls, beha, hitting, true, empty[0], empty[1], - you.level_type, 0, zsec, dur ); - } - - // determine whether creating a monster is successful (summd != -1) {dlb}: - // then handle the outcome {dlb}: - if (summd == -1) - { - if (see_grid( cr_x, cr_y )) - mpr("You see a puff of smoke."); - } - else - { - struct monsters *const creation = &menv[summd]; - - // dur should always be ENCH_ABJ_xx - if (dur >= ENCH_ABJ_I && dur <= ENCH_ABJ_VI) - mons_add_ench(creation, dur ); - - // look at special cases: CHARMED, FRIENDLY, HOSTILE, GOD_GIFT - // alert summoned being to player's presence - if (beha > NUM_BEHAVIOURS) - { - if (beha == BEH_FRIENDLY || beha == BEH_GOD_GIFT) - creation->flags |= MF_CREATED_FRIENDLY; - - if (beha == BEH_GOD_GIFT) - creation->flags |= MF_GOD_GIFT; - - if (beha == BEH_CHARMED) - { - creation->attitude = ATT_HOSTILE; - mons_add_ench(creation, ENCH_CHARM); - } - - // make summoned being aware of player's presence - behaviour_event(creation, ME_ALERT, MHITYOU); - } - - if (creation->type == MONS_RAKSHASA_FAKE && !one_chance_in(3)) - mons_add_ench(creation, ENCH_INVIS); - } - - // the return value is either -1 (failure of some sort) - // or the index of the monster placed (if I read things right) {dlb} - return (summd); -} // end create_monster() - - -bool empty_surrounds(int emx, int emy, unsigned char spc_wanted, - bool allow_centre, FixedVector < char, 2 > &empty) -{ - bool success; - // assume all player summoning originates from player x,y - bool playerSummon = (emx == you.x_pos && emy == you.y_pos); - - int xpos[25]; // good x pos - int ypos[25]; // good y pos - int good_count = 0; - int count_x, count_y; - - char minx = -2; - char maxx = 2; - char miny = -2; - char maxy = 2; - - for (count_x = minx; count_x <= maxx; count_x++) - { - for (count_y = miny; count_y <= maxy; count_y++) - { - success = false; - - if (!allow_centre && count_x == 0 && count_y == 0) - continue; - - int tx = emx + count_x; - int ty = emy + count_y; - - if (tx == you.x_pos && ty == you.y_pos) - continue; - - if (mgrd[tx][ty] != NON_MONSTER) - continue; - - // players won't summon out of LOS - if (!see_grid(tx, ty) && playerSummon) - continue; - - if (grd[tx][ty] == spc_wanted) - success = true; - - // those seeking ground can stand in shallow water or better - if (spc_wanted == DNGN_FLOOR && grd[tx][ty] >= DNGN_SHALLOW_WATER) - success = true; - - // water monsters can be created in shallow as well as deep water - if (spc_wanted == DNGN_DEEP_WATER && grd[tx][ty] == DNGN_SHALLOW_WATER) - success = true; - - if (success) - { - // add point to list of good points - xpos[good_count] = tx; - ypos[good_count] = ty; - good_count ++; - } - } // end "for count_y" - } // end "for count_x" - - if (good_count > 0) - { - int pick = random2(good_count); - empty[0] = xpos[pick]; - empty[1] = ypos[pick]; - } - - return (good_count > 0); -} // end empty_surrounds() - -int summon_any_demon(char demon_class) -{ - int summoned; // error trapping {dlb} - int temp_rand; // probability determination {dlb} - - switch (demon_class) - { - case DEMON_LESSER: - temp_rand = random2(60); - summoned = ((temp_rand > 49) ? MONS_IMP : // 10 in 60 - (temp_rand > 40) ? MONS_WHITE_IMP : // 9 in 60 - (temp_rand > 31) ? MONS_LEMURE : // 9 in 60 - (temp_rand > 22) ? MONS_UFETUBUS : // 9 in 60 - (temp_rand > 13) ? MONS_MANES : // 9 in 60 - (temp_rand > 4) ? MONS_MIDGE // 9 in 60 - : MONS_SHADOW_IMP); // 5 in 60 - break; - - case DEMON_COMMON: - temp_rand = random2(3948); - summoned = ((temp_rand > 3367) ? MONS_NEQOXEC : // 14.69% - (temp_rand > 2787) ? MONS_ORANGE_DEMON : // 14.69% - (temp_rand > 2207) ? MONS_HELLWING : // 14.69% - (temp_rand > 1627) ? MONS_SMOKE_DEMON : // 14.69% - (temp_rand > 1047) ? MONS_YNOXINUL : // 14.69% - (temp_rand > 889) ? MONS_RED_DEVIL : // 4.00% - (temp_rand > 810) ? MONS_HELLION : // 2.00% - (temp_rand > 731) ? MONS_ROTTING_DEVIL : // 2.00% - (temp_rand > 652) ? MONS_TORMENTOR : // 2.00% - (temp_rand > 573) ? MONS_REAPER : // 2.00% - (temp_rand > 494) ? MONS_SOUL_EATER : // 2.00% - (temp_rand > 415) ? MONS_HAIRY_DEVIL : // 2.00% - (temp_rand > 336) ? MONS_ICE_DEVIL : // 2.00% - (temp_rand > 257) ? MONS_BLUE_DEVIL : // 2.00% - (temp_rand > 178) ? MONS_BEAST : // 2.00% - (temp_rand > 99) ? MONS_IRON_DEVIL : // 2.00% - (temp_rand > 49) ? MONS_SUN_DEMON // 1.26% - : MONS_SHADOW_IMP); // 1.26% - break; - - case DEMON_GREATER: - temp_rand = random2(1000); - summoned = ((temp_rand > 868) ? MONS_CACODEMON : // 13.1% - (temp_rand > 737) ? MONS_BALRUG : // 13.1% - (temp_rand > 606) ? MONS_BLUE_DEATH : // 13.1% - (temp_rand > 475) ? MONS_GREEN_DEATH : // 13.1% - (temp_rand > 344) ? MONS_EXECUTIONER : // 13.1% - (temp_rand > 244) ? MONS_FIEND : // 10.0% - (temp_rand > 154) ? MONS_ICE_FIEND : // 9.0% - (temp_rand > 73) ? MONS_SHADOW_FIEND // 8.1% - : MONS_PIT_FIEND); // 7.4% - break; - - default: - summoned = MONS_GIANT_ANT; // this was the original behaviour {dlb} - break; - } - - return summoned; -} // end summon_any_demon() - -monster_type rand_dragon( dragon_class_type type ) -{ - monster_type summoned = MONS_PROGRAM_BUG; - int temp_rand; - - switch (type) - { - case DRAGON_LIZARD: - temp_rand = random2(100); - summoned = ((temp_rand > 85) ? MONS_GIANT_GECKO : - (temp_rand > 59) ? MONS_GIANT_LIZARD : - (temp_rand > 34) ? MONS_GIANT_IGUANA : - (temp_rand > 22) ? MONS_GILA_MONSTER : - (temp_rand > 11) ? MONS_KOMODO_DRAGON : - (temp_rand > 8) ? MONS_FIREDRAKE : - (temp_rand > 2) ? MONS_SWAMP_DRAKE - : MONS_DEATH_DRAKE ); - break; - - case DRAGON_DRACONIAN: - temp_rand = random2(70); - summoned = ((temp_rand > 60) ? MONS_YELLOW_DRACONIAN : - (temp_rand > 50) ? MONS_BLACK_DRACONIAN : - (temp_rand > 40) ? MONS_PALE_DRACONIAN : - (temp_rand > 30) ? MONS_GREEN_DRACONIAN : - (temp_rand > 20) ? MONS_PURPLE_DRACONIAN : - (temp_rand > 10) ? MONS_RED_DRACONIAN - : MONS_WHITE_DRACONIAN); - break; - - case DRAGON_DRAGON: - temp_rand = random2(90); - summoned = ((temp_rand > 80) ? MONS_MOTTLED_DRAGON : - (temp_rand > 70) ? MONS_LINDWURM : - (temp_rand > 60) ? MONS_STORM_DRAGON : - (temp_rand > 50) ? MONS_MOTTLED_DRAGON : - (temp_rand > 40) ? MONS_STEAM_DRAGON : - (temp_rand > 30) ? MONS_DRAGON : - (temp_rand > 20) ? MONS_ICE_DRAGON : - (temp_rand > 10) ? MONS_SWAMP_DRAGON - : MONS_SHADOW_DRAGON); - break; - - default: - break; - } - - return (summoned); -} |