From 0e65534b50e40a32611842551af39a089eff48af Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Mon, 30 Jun 2008 14:32:21 +0000 Subject: Enable Chaos Knights of Lugonu starting out in the Abyss. I've marked these characters with GDT_GAME_START, so that * the player starts out on an altar to Lugonu * there's an exit back to the Dungeon near-by * returning into the Dungeon always places them into the entry vault on level 1 * no abyssal runes are ever generated * item generation matches that of level 1 * monster spawn rates are that of the orb run to enforce a quick return into the Dungeon Once the player returns to the Dungeon (via an exit or with Lugonu's first power) char_direction is properly set to GDT_DESCENDING and from then on the game continues as if they had started in the Dungeon. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6245 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/abyss.cc | 74 +++++++++++++++++++++++++++++++------------- crawl-ref/source/acr.cc | 10 ++++-- crawl-ref/source/dungeon.cc | 8 ++--- crawl-ref/source/enum.h | 2 +- crawl-ref/source/files.cc | 39 +++++++++++++++++++++-- crawl-ref/source/initfile.cc | 21 +++++++------ crawl-ref/source/makeitem.cc | 4 +-- crawl-ref/source/misc.cc | 14 ++++----- crawl-ref/source/newgame.cc | 47 +++++++++++++++++++++------- crawl-ref/source/player.cc | 2 +- crawl-ref/source/religion.cc | 3 +- 11 files changed, 162 insertions(+), 62 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index 416515d1e9..14ab8056bd 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -90,11 +90,24 @@ void generate_abyss() : DNGN_CLOSED_DOOR); // 1 in 4000 } - grd[45][35] = DNGN_FLOOR; - if (one_chance_in(5)) + // If we're starting out in the Abyss, make sure the starting grid is + // an altar to Lugonu and there's an exit near-by. + // Otherwise, we start out on floor and there's a chance there's an + // altar near-by. + if (you.char_direction == GDT_GAME_START) { + grd[45][35] = DNGN_ALTAR_LUGONU; _place_feature_near( coord_def(45, 35), LOS_RADIUS, - DNGN_FLOOR, DNGN_ALTAR_LUGONU, 50 ); + DNGN_FLOOR, DNGN_EXIT_ABYSS, 50 ); + } + else + { + grd[45][35] = DNGN_FLOOR; + if (one_chance_in(5)) + { + _place_feature_near( coord_def(45, 35), LOS_RADIUS, + DNGN_FLOOR, DNGN_ALTAR_LUGONU, 50 ); + } } } @@ -209,6 +222,7 @@ static void _generate_area(int gx1, int gy1, int gx2, int gy2, if (items_placed < 150 && one_chance_in(200)) { if (!placed_abyssal_rune && abyssal_rune_roll != -1 + && you.char_direction != GDT_GAME_START && one_chance_in(abyssal_rune_roll)) { thing_created = items(1, OBJ_MISCELLANY, @@ -220,8 +234,19 @@ static void _generate_area(int gx1, int gy1, int gx2, int gy2, } else { - thing_created = items(1, OBJ_RANDOM, - OBJ_RANDOM, true, 51, 250); + if (you.char_direction == GDT_GAME_START) + { + // Number and level of items as that on level 1. + const int num_items = 3 + roll_dice( 3, 11 ); + const int items_level = 0; + thing_created = items(1, OBJ_RANDOM, OBJ_RANDOM, + true, items_level, num_items); + } + else + { + thing_created = items(1, OBJ_RANDOM, + OBJ_RANDOM, true, 51, 250); + } } move_item_to_grid( &thing_created, i, j ); @@ -254,29 +279,34 @@ static void _generate_area(int gx1, int gy1, int gx2, int gy2, #endif } - if (one_chance_in(10000)) // Place an altar. - altars_wanted++; - - // Don't place altars under items. - if (altars_wanted > 0 && igrd[i][j] == NON_ITEM) + // Except for the altar on the starting position, don't place + // any altars. + if (you.char_direction != GDT_GAME_START) { - do + if (one_chance_in(10000)) // Place an altar. + altars_wanted++; + + // Don't place altars under items. + if (altars_wanted > 0 && igrd[i][j] == NON_ITEM) { - grd[i][j] = static_cast( - DNGN_ALTAR_ZIN + random2(NUM_GODS-1) ); - } - while (grd[i][j] == DNGN_ALTAR_ZIN - || grd[i][j] == DNGN_ALTAR_SHINING_ONE - || grd[i][j] == DNGN_ALTAR_ELYVILON); + do + { + grd[i][j] = static_cast( + DNGN_ALTAR_ZIN + random2(NUM_GODS-1) ); + } + while (grd[i][j] == DNGN_ALTAR_ZIN + || grd[i][j] == DNGN_ALTAR_SHINING_ONE + || grd[i][j] == DNGN_ALTAR_ELYVILON); - // Lugonu has a flat 50% chance of corrupting the altar. - if (coinflip()) - grd[i][j] = DNGN_ALTAR_LUGONU; + // Lugonu has a flat 50% chance of corrupting the altar. + if (coinflip()) + grd[i][j] = DNGN_ALTAR_LUGONU; - altars_wanted--; + altars_wanted--; #if DEBUG_ABYSS - mpr("Placing altar.", MSGCH_DIAGNOSTICS); + mpr("Placing altar.", MSGCH_DIAGNOSTICS); #endif + } } } diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 8bf0afedfb..539350f581 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -4023,6 +4023,12 @@ static bool _initialise(void) run_map_preludes(); + if (newc && you.char_direction == GDT_GAME_START) + { + // Chaos Knights of Lugonu start out in the Abyss. + you.level_type = LEVEL_ABYSS; + you.entry_cause = EC_UNKNOWN; + } load( you.entering_level? you.transit_stair : DNGN_STONE_STAIRS_DOWN_I, you.entering_level? LOAD_ENTER_LEVEL : newc ? LOAD_START_GAME : LOAD_RESTART_GAME, @@ -4321,8 +4327,8 @@ static void _move_player(int move_x, int move_y) you.running = RMODE_CONTINUE; if (you.level_type == LEVEL_ABYSS - && (you.x_pos <= 15 || you.x_pos >= (GXM - 16) - || you.y_pos <= 15 || you.y_pos >= (GYM - 16))) + && (you.x_pos <= 15 || you.x_pos >= (GXM - 16) + || you.y_pos <= 15 || you.y_pos >= (GYM - 16))) { area_shift(); if (you.pet_target != MHITYOU) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 09cd0d6cce..3a5d8035a9 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -278,7 +278,7 @@ static callback_map level_type_post_callbacks; *********************************************************************/ bool builder(int level_number, int level_type) { - const std::set uniq_tags = you.uniq_map_tags; + const std::set uniq_tags = you.uniq_map_tags; const std::set uniq_names = you.uniq_map_names; // N tries to build the level, after which we bail with a capital B. @@ -3052,9 +3052,9 @@ static void _builder_items(int level_number, char level_type, int items_wanted) // 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].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 } } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 7390fc2308..764f3f2dc5 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -765,7 +765,7 @@ enum description_level_type enum game_direction_type { - GDT_NONE, + GDT_GAME_START = 0, GDT_DESCENDING, GDT_ASCENDING }; diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index e20fefc3b9..78a766b910 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1036,6 +1036,11 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, you.transit_stair, stair_taken, DNGN_UNSEEN); unwind_bool ylev(you.entering_level, true, false); +#ifdef DEBUG_LEVEL_LOAD + mprf(MSGCH_DIAGNOSTICS, "Loading... level type: %d, branch: %d, level: %d", + you.level_type, you.where_are_you, you.your_level); +#endif + // Going up/down stairs, going through a portal, or being banished // means the previous x/y movement direction is no longer valid. you.reset_prev_move(); @@ -1087,14 +1092,31 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, _do_lost_items(old_level_type); // Try to open level savefile. +#ifdef DEBUG_LEVEL_LOAD + mprf(MSGCH_DIAGNOSTICS, "Try to open file %s", cha_fil.c_str()); +#endif FILE *levelFile = fopen(cha_fil.c_str(), "rb"); // GENERATE new level when the file can't be opened: if (levelFile == NULL) { +#ifdef DEBUG_LEVEL_LOAD + mpr("Generating new file...", MSGCH_DIAGNOSTICS); +#endif ASSERT( load_mode != LOAD_VISITOR ); env.turns_on_level = -1; - builder( you.your_level, you.level_type ); + + if (you.char_direction == GDT_GAME_START + && you.level_type == LEVEL_DUNGEON) + { + // If we're leaving the Abyss for the first time as a Chaos Knight + // of Lugonu (who start out there), force a return into the first + // dungeon level and enable normal monster generation. + you.your_level = 0; + you.char_direction = GDT_DESCENDING; + } + + builder(you.your_level, you.level_type); just_created_level = true; if ((you.your_level > 1 || you.level_type != LEVEL_DUNGEON) @@ -1109,6 +1131,9 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, } else { +#ifdef DEBUG_LEVEL_LOAD + mpr("Loading old file...", MSGCH_DIAGNOSTICS); +#endif // BEGIN -- must load the old level : pre-load tasks // LOAD various tags @@ -1245,7 +1270,7 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, if (load_mode != LOAD_VISITOR) crawl_state.level_annotation_shown = false; - if ( make_changes ) + if (make_changes) { // Update PlaceInfo entries PlaceInfo& curr_PlaceInfo = you.get_place_info(); @@ -1263,9 +1288,19 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode, delta.levels_seen++; you.global_info += delta; +#ifdef DEBUG_LEVEL_LOAD + mprf(MSGCH_DIAGNOSTICS, + "global_info:: num_visits: %d, levels_seen: %d", + you.global_info.num_visits, you.global_info.levels_seen); +#endif you.global_info.assert_validity(); curr_PlaceInfo += delta; +#ifdef DEBUG_LEVEL_LOAD + mprf(MSGCH_DIAGNOSTICS, + "curr_PlaceInfo:: num_visits: %d, levels_seen: %d", + curr_PlaceInfo.num_visits, curr_PlaceInfo.levels_seen); +#endif curr_PlaceInfo.assert_validity(); } diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index bbf41a480c..c1c59a9d37 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -1220,16 +1220,17 @@ static void write_newgame_options(FILE *f) if (Options.prev_ck != GOD_NO_GOD) { fprintf(f, "chaos_knight = %s\n", - Options.prev_ck == GOD_XOM? "xom" : - Options.prev_ck == GOD_MAKHLEB? "makhleb" : - "random"); + Options.prev_ck == GOD_XOM ? "xom" : + Options.prev_ck == GOD_MAKHLEB ? "makhleb" : + Options.prev_ck == GOD_LUGONU ? "lugonu" + : "random"); } if (Options.prev_dk != DK_NO_SELECTION) { fprintf(f, "death_knight = %s\n", - Options.prev_dk == DK_NECROMANCY? "necromancy" : - Options.prev_dk == DK_YREDELEMNUL? "yredelemnul" : - "random"); + Options.prev_dk == DK_NECROMANCY ? "necromancy" : + Options.prev_dk == DK_YREDELEMNUL ? "yredelemnul" + : "random"); } if (is_priest_god(Options.prev_pr) || Options.prev_pr == GOD_RANDOM) { @@ -2035,21 +2036,23 @@ void game_options::read_option_line(const std::string &str, bool runscript) else COLOUR_OPTION(status_caption_colour); else if (key == "weapon") { - // choose this weapon for classes that get choice + // Choose this weapon for classes that get choice. weapon = _str_to_weapon( field ); } else if (key == "book") { - // choose this book for classes that get choice + // Choose this book for classes that get choice. book = _str_to_book( field ); } else if (key == "chaos_knight") { - // choose god for Chaos Knights + // Choose god for Chaos Knights. if (field == "xom") chaos_knight = GOD_XOM; else if (field == "makhleb") chaos_knight = GOD_MAKHLEB; + else if (field == "lugonu") + chaos_knight = GOD_LUGONU; else if (field == "random") chaos_knight = GOD_RANDOM; } diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 238b3adefb..0824c476c2 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -2677,7 +2677,7 @@ static void _generate_misc_item(item_def& item, int force_type, int item_race) item.plus = item_race; } -// Returns item slot or NON_ITEM if it fails +// Returns item slot or NON_ITEM if it fails. int items( int allow_uniques, // not just true-false, // because of BCR acquirement hack object_class_type force_class, // desired OBJECTS class {dlb} @@ -2699,7 +2699,7 @@ int items( int allow_uniques, // not just true-false, || force_class == OBJ_MISSILES) && force_type != OBJ_RANDOM); - // find an empty slot for the item (with culling if required) + // Find an empty slot for the item (with culling if required). int p = get_item_slot(10); if (p == NON_ITEM) return (NON_ITEM); diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 5d3e01675f..a7a8002049 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -1475,8 +1475,8 @@ bool check_annotation_exclusion_warning() void up_stairs(dungeon_feature_type force_stair, entry_cause_type entry_cause) { - dungeon_feature_type stair_find = - force_stair? force_stair : grd[you.x_pos][you.y_pos]; + dungeon_feature_type stair_find = (force_stair ? force_stair + : grd[you.x_pos][you.y_pos]); const branch_type old_where = you.where_are_you; const level_area_type old_level_type = you.level_type; @@ -1822,7 +1822,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, // reaching the Abyss. if (grd[you.x_pos][you.y_pos] == DNGN_ENTER_ABYSS) mark_milestone("abyss.enter", "entered the Abyss!"); - else if (grd[you.x_pos][you.y_pos] == DNGN_EXIT_ABYSS)Picture + else if (grd[you.x_pos][you.y_pos] == DNGN_EXIT_ABYSS) mark_milestone("abyss.exit", "escaped from the Abyss!"); } #endif @@ -2024,7 +2024,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (entered_branch) { - if ( branches[you.where_are_you].entry_message ) + if (branches[you.where_are_you].entry_message) mpr(branches[you.where_are_you].entry_message); else mprf("Welcome to %s!", branches[you.where_are_you].longname); @@ -2052,7 +2052,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (god_gives_permanent_followers(you.religion)) you.friendly_pickup = Options.default_friendly_pickup; - switch(you.level_type) + switch (you.level_type) { case LEVEL_DUNGEON: xom_is_stimulated(49); @@ -2137,7 +2137,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (player_in_hell()) { you.where_are_you = BRANCH_MAIN_DUNGEON; - you.your_level = you.hell_exit - 1; + you.your_level = you.hell_exit - 1; } break; @@ -2158,7 +2158,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (player_in_hell()) { you.where_are_you = BRANCH_MAIN_DUNGEON; - you.hell_exit = 26; + you.hell_exit = 26; you.your_level = 26; } } diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index 9e97a0b439..b2327bc9ae 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -1937,6 +1937,8 @@ static char_choice_restriction _book_restriction(int booktype, return (CC_UNRESTRICTED); default: + if (!summon_too && player_genus(GENPC_DRACONIAN)) + return (CC_UNRESTRICTED); return (CC_RESTRICTED); } break; @@ -1965,6 +1967,8 @@ static char_choice_restriction _book_restriction(int booktype, return (CC_UNRESTRICTED); default: + if (!summon_too && player_genus(GENPC_DRACONIAN)) + return (CC_UNRESTRICTED); return (CC_RESTRICTED); } break; @@ -1988,8 +1992,9 @@ static char_choice_restriction _book_restriction(int booktype, break; default: - return (player_genus(GENPC_DRACONIAN) ? CC_UNRESTRICTED - : CC_RESTRICTED); + if (player_genus(GENPC_DRACONIAN)) + return (CC_UNRESTRICTED); + return (CC_RESTRICTED); } } return (CC_RESTRICTED); @@ -2076,9 +2081,9 @@ static bool _choose_book( item_def& book, int firstbook, int numbooks ) return (false); case '\r': case '\n': - if ( Options.prev_book != SBT_NO_SELECTION ) + if (Options.prev_book != SBT_NO_SELECTION) { - if ( Options.prev_book == SBT_RANDOM ) + if (Options.prev_book == SBT_RANDOM) keyin = '*'; else keyin = ('a' + Options.prev_book - 1); @@ -4228,6 +4233,7 @@ bool _give_items_skills() keyn = '*'; // for ng_pr setting // fall-through for random case '*': + case '+': you.religion = coinflip() ? GOD_ZIN : GOD_YREDELEMNUL; if (you.species == SP_HILL_ORC && coinflip()) you.religion = GOD_BEOGH; @@ -4906,7 +4912,9 @@ bool _give_items_skills() } else if (Options.random_pick || Options.chaos_knight == GOD_RANDOM) { - you.religion = coinflip() ? GOD_XOM : GOD_MAKHLEB; + you.religion = (one_chance_in(3) ? GOD_XOM : + coinflip() ? GOD_MAKHLEB + : GOD_LUGONU); ng_ck = GOD_RANDOM; } else @@ -4920,6 +4928,7 @@ bool _give_items_skills() textcolor( LIGHTGREY ); cprintf("a - Xom of Chaos" EOL); cprintf("b - Makhleb the Destroyer" EOL); + cprintf("c - Lugonu the Unformed" EOL); textcolor( BROWN ); cprintf(EOL "* - Random choice; " @@ -4931,7 +4940,8 @@ bool _give_items_skills() textcolor(BROWN); cprintf(EOL "Enter - %s" EOL, Options.prev_ck == GOD_XOM ? "Xom" : - Options.prev_ck == GOD_MAKHLEB ? "Makhleb" + Options.prev_ck == GOD_MAKHLEB ? "Makhleb" : + Options.prev_ck == GOD_LUGONU ? "Lugonu" : "Random"); textcolor(LIGHTGREY); } @@ -4963,14 +4973,20 @@ bool _give_items_skills() keyn = '*'; // for ng_ck setting // fall-through for random case '*': - you.religion = (coinflip()? GOD_XOM : GOD_MAKHLEB); + case '+': + you.religion = (one_chance_in(3) ? GOD_XOM : + coinflip() ? GOD_MAKHLEB + : GOD_LUGONU); break; case 'a': you.religion = GOD_XOM; break; case 'b': you.religion = GOD_MAKHLEB; - // fall through + break; + case 'c': + you.religion = GOD_LUGONU; + break; default: break; } @@ -4992,12 +5008,21 @@ bool _give_items_skills() // (Namely, a countdown to becoming bored.) you.gift_timeout = random2(40) + random2(40); } - else // Makhleb + else // Makhleb or Lugonu { - you.piety = 25; you.skills[SK_INVOCATIONS] = 2; - } + if (you.religion == GOD_LUGONU) + { + // Chaos Knights of Lugonu start in the Abyss. We need to mark + // this unusual occurence, so the player doesn't get early + // access to OOD items etc. + you.char_direction = GDT_GAME_START; + you.piety = 35; + } + else + you.piety = 25; + } break; case JOB_HEALER: diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 746b2f6948..451b22f347 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6719,7 +6719,7 @@ void PlaceInfo::assert_validity() const && branch == -1); // Can't have visited a place without seeing any of its levels, and - // visa versa + // visa versa. ASSERT(num_visits == 0 && levels_seen == 0 || num_visits > 0 && levels_seen > 0); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 8c0c97ca2a..63c0236193 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -438,7 +438,8 @@ bool is_good_god(god_type god) bool is_chaotic_god(god_type god) { return (god == GOD_XOM - || god == GOD_MAKHLEB); + || god == GOD_MAKHLEB + || god == GOD_LUGONU); } bool is_priest_god(god_type god) -- cgit v1.2.3-54-g00ecf