From 9629076ee9f0b7a88048c0eb6d979c5d86a7a3d2 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Wed, 26 Nov 2008 04:49:33 +0000 Subject: Start of moving special room definitions (monster lairs and monster pits) to lua. As of now all special rooms are filled with rats. Introduces two new members to map_def, weight_depth_mult and weight_depth_div, which change a map's weight based on the absolute dungeon depth (not yet accesible via lua or vault definitions). This needs to be done in C++ rather than in lua since a map's lua isn't re-invoked every time a random map is chosen, but only when the map is placed. NOTE: When I first made this change crawl started crashing until I manually forced the recompilation of util/levcomp.lex.o and util/levcomp.tab.o; if crawl starts crashing after this change, try doing that. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7629 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/dungeon.cc | 268 ++++++++++++++++++++++++-------------------- 1 file changed, 144 insertions(+), 124 deletions(-) (limited to 'crawl-ref/source/dungeon.cc') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index a10f46b80b..5255a053fe 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -58,13 +58,8 @@ #include "cio.h" // for cancelable_get_line() #endif -#define MAX_PIT_MONSTERS 10 - -struct pit_mons_def -{ - monster_type type; - int rare; -}; +spec_room lua_special_room_spec; +int lua_special_room_level; struct dist_feat { @@ -189,9 +184,6 @@ static void _chequerboard(spec_room &sr, dungeon_feature_type target, dungeon_feature_type floor1, dungeon_feature_type floor2); static void _roguey_level(int level_number, spec_room &sr, bool make_stairs); -static void _morgue(spec_room &sr); -static void _beehive(spec_room &sr); -static void _jelly_pit(int level_number, spec_room &sr); // VAULT FUNCTIONS static bool _build_secondary_vault(int level_number, const map_def *vault, @@ -925,6 +917,10 @@ static void _reset_level() env.floor_colour = BLACK; env.rock_colour = BLACK; + + lua_special_room_spec.created = false; + lua_special_room_spec.tl.set(-1, -1); + lua_special_room_level = -1; } static void _build_layout_skeleton(int level_number, int level_type, @@ -3524,83 +3520,9 @@ static void _specr_2(spec_room &sr) sr.hooked_up = true; } -// 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_list, int density, - monster_type lord_type, const coord_def& lordpos) -{ - int i; - - // 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) - { - const int delta = ((i > 0) ? pit_list[i].rare - pit_list[i - 1].rare - : pit_list[i].rare); - - const float perc = (static_cast( delta ) * 100.0) - / static_cast( rare_sum ); - - mprf( MSGCH_DIAGNOSTICS, "%6.2f%%: %s", perc, - mons_type_name( pit_list[i].type, DESC_PLAIN).c_str() ); - } -#endif - - // Put the boss monster down. - if (lord_type != MONS_PROGRAM_BUG) - { - mgen_data mg; - mg.cls = lord_type; - mg.behaviour = BEH_SLEEP; - mg.pos = lordpos; - - mons_place(mgen_data::sleeper_at(lord_type, lordpos)); - } - - // Place monsters and give them items {dlb}: - for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) - { - // Avoid the boss (or anyone else we may have dropped already). - if (mgrd(*ri) != NON_MONSTER) - continue; - - const int roll = random2( die_size ); - - // Density skip (no need to iterate). - if (roll >= rare_sum) - continue; - - // Run through the cumulative chances and place a monster. - for (i = 0; i < num_types; ++i) - { - if (roll < pit_list[i].rare) - { - mons_place( - mgen_data::sleeper_at(pit_list[i].type, *ri)); - break; - } - } - } -} - static void _special_room(int level_number, spec_room &sr) { +#if 0 // MATT char spec_room_type = SROOM_LAIR_KOBOLD; int lev_mons; int thing_created = 0; @@ -3611,6 +3533,7 @@ static void _special_room(int level_number, spec_room &sr) FixedVector < monster_type, 10 > mons_alloc; // was [20] {dlb} coord_def lordpos; +#endif // Overwrites anything: this function better be called early on during // creation. @@ -3629,6 +3552,25 @@ static void _special_room(int level_number, spec_room &sr) sr.tl.set(room_x1 + 1, room_y1 + 1); sr.br.set(room_x2 - 1, room_y2 - 1); + const map_def *vault = random_map_for_tag("special_room", true, true); + + ASSERT(vault); + if (!vault) + { + mpr("ERROR: failed to create special room.", MSGCH_ERROR); + return; + } + + lua_special_room_spec = sr; + lua_special_room_level = level_number; + + _build_minivaults( level_number, vault, false, false, sr.tl); + + lua_special_room_spec.created = false; + lua_special_room_spec.tl.set(-1, -1); + lua_special_room_level = -1; + +#if 0 // MATT if (level_number < 7) spec_room_type = SROOM_LAIR_KOBOLD; else @@ -3774,47 +3716,9 @@ static void _special_room(int level_number, spec_room &sr) _jelly_pit(level_number, sr); break; } +#endif } // end special_room() -// Fills a special room with bees. -static void _beehive(spec_room &sr) -{ - for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) - { - if (coinflip()) - continue; - - const int i = get_item_slot(); - if (i == NON_ITEM) - continue; - - item_def& item(mitm[i]); - - item.quantity = 1; - item.base_type = OBJ_FOOD; - item.sub_type = (one_chance_in(25) ? FOOD_ROYAL_JELLY : FOOD_HONEYCOMB); - item.pos = *ri; - item_colour( item ); - } - - const coord_def queenpos(sr.random_spot()); - - // Mark all kinds of bees at patrolling to make them return to their hive. - for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) - { - if (*ri == queenpos) - continue; - - // The hive is chock full of bees! - mons_place(mgen_data::sleeper_at( - one_chance_in(7) ? MONS_KILLER_BEE_LARVA - : MONS_KILLER_BEE, - *ri, MG_PATROLLING)); - } - - mons_place(mgen_data::sleeper_at(MONS_QUEEN_BEE, queenpos, MG_PATROLLING)); -} - // Used for placement of vaults. static bool _may_overwrite_feature(const dungeon_feature_type grid, bool water_ok, bool rock_ok = true) @@ -7462,6 +7366,82 @@ static void _roguey_level(int level_number, spec_room &sr, bool make_stairs) } } // end roguey_level() +#if 0 // MATT +// 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_list, int density, + monster_type lord_type, const coord_def& lordpos) +{ + int i; + + // 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) + { + const int delta = ((i > 0) ? pit_list[i].rare - pit_list[i - 1].rare + : pit_list[i].rare); + + const float perc = (static_cast( delta ) * 100.0) + / static_cast( rare_sum ); + + mprf( MSGCH_DIAGNOSTICS, "%6.2f%%: %s", perc, + mons_type_name( pit_list[i].type, DESC_PLAIN).c_str() ); + } +#endif + + // Put the boss monster down. + if (lord_type != MONS_PROGRAM_BUG) + { + mgen_data mg; + mg.cls = lord_type; + mg.behaviour = BEH_SLEEP; + mg.pos = lordpos; + + mons_place(mgen_data::sleeper_at(lord_type, lordpos)); + } + + // Place monsters and give them items {dlb}: + for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) + { + // Avoid the boss (or anyone else we may have dropped already). + if (mgrd(*ri) != NON_MONSTER) + continue; + + const int roll = random2( die_size ); + + // Density skip (no need to iterate). + if (roll >= rare_sum) + continue; + + // Run through the cumulative chances and place a monster. + for (i = 0; i < num_types; ++i) + { + if (roll < pit_list[i].rare) + { + mons_place( + mgen_data::sleeper_at(pit_list[i].type, *ri)); + break; + } + } + } +} + static void _morgue(spec_room &sr) { for (rectangle_iterator ri(sr.tl, sr.br); ri; ++ri) @@ -7523,6 +7503,46 @@ static void _jelly_pit(int level_number, spec_room &sr) _fill_monster_pit( sr, pit_list, 90, MONS_PROGRAM_BUG, lordpos ); } +// Fills a special room with bees. +static void _beehive(spec_room &sr) +{ + for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) + { + if (coinflip()) + continue; + + const int i = get_item_slot(); + if (i == NON_ITEM) + continue; + + item_def& item(mitm[i]); + + item.quantity = 1; + item.base_type = OBJ_FOOD; + item.sub_type = (one_chance_in(25) ? FOOD_ROYAL_JELLY : FOOD_HONEYCOMB); + item.pos = *ri; + item_colour( item ); + } + + const coord_def queenpos(sr.random_spot()); + + // Mark all kinds of bees at patrolling to make them return to their hive. + for ( rectangle_iterator ri(sr.tl, sr.br); ri; ++ri ) + { + if (*ri == queenpos) + continue; + + // The hive is chock full of bees! + mons_place(mgen_data::sleeper_at( + one_chance_in(7) ? MONS_KILLER_BEE_LARVA + : MONS_KILLER_BEE, + *ri, MG_PATROLLING)); + } + + mons_place(mgen_data::sleeper_at(MONS_QUEEN_BEE, queenpos, MG_PATROLLING)); +} +#endif + bool place_specific_trap(const coord_def& where, trap_type spec_type) { if (spec_type == TRAP_RANDOM || spec_type == TRAP_NONTELEPORT) -- cgit v1.2.3-54-g00ecf