summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/newgame.cc
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-04-25 20:32:48 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-04-25 20:32:48 +0000
commitc319b212cbe4a79fdbc4e3efac8530d1e9ffab6f (patch)
tree62798731b22ab12a1a326b4e04060e5a74b6f879 /crawl-ref/source/newgame.cc
parente46965c192b6ddc04357366a2f136d6e2115bb59 (diff)
downloadcrawl-ref-c319b212cbe4a79fdbc4e3efac8530d1e9ffab6f.tar.gz
crawl-ref-c319b212cbe4a79fdbc4e3efac8530d1e9ffab6f.zip
Various cleanups. Also fixed bug 1703500, inventory letters appearing twice
until save/restore. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1371 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/newgame.cc')
-rw-r--r--crawl-ref/source/newgame.cc506
1 files changed, 267 insertions, 239 deletions
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index 3266dfc497..b936b6d44a 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -372,120 +372,200 @@ static void initialise_branch_depths()
branches[BRANCH_TOMB].startdepth = random_range(2, 3);
}
-bool new_game(void)
+static void initialise_item_descriptions()
{
- int i, j; // loop variables {dlb}
+ // must remember to check for already existing colours/combinations
+ you.item_description.init(255);
- //jmf: NEW ASSERTS: we ought to do a *lot* of these
- ASSERT(NUM_SPELLS < SPELL_NO_SPELL);
- ASSERT(NUM_JOBS < JOB_UNKNOWN);
- ASSERT(NUM_ATTRIBUTES >= 30);
+ you.item_description[IDESC_POTIONS][POT_PORRIDGE] =
+ PDESCQ(PDQ_GLUGGY, PDC_WHITE);
- init_player();
+ you.item_description[IDESC_POTIONS][POT_WATER] = PDESCS(PDC_CLEAR);
- if (!Options.player_name.empty())
+ for (int i = 0; i < NUM_IDESC; i++)
{
- strncpy(you.your_name, Options.player_name.c_str(), kNameLen);
- you.your_name[kNameLen - 1] = 0;
- }
+ // We really should only loop until NUM_WANDS, etc., here
+ for (int j = 0; j < you.item_description.height(); j++)
+ {
+ // Don't override predefines
+ if (you.item_description[i][j] != 255)
+ continue;
- textcolor(LIGHTGREY);
+ // pick a new description until it's good
+ while (true)
+ {
- // copy name into you.your_name if set from environment --
- // note that you.your_name could already be set from init.txt
- // this, clearly, will overwrite such information {dlb}
- if (SysEnv.crawl_name)
- {
- strncpy( you.your_name, SysEnv.crawl_name, kNameLen );
- you.your_name[ kNameLen - 1 ] = 0;
- }
+ switch (i)
+ {
+ case IDESC_WANDS: // wands
+ you.item_description[i][j] = random2( 16 * 12 );
+ if (coinflip())
+ you.item_description[i][j] %= 12;
+ break;
- openingScreen();
- enter_player_name(true);
+ case IDESC_POTIONS: // potions
+ you.item_description[i][j] = random_potion_description();
+ break;
- if (you.your_name[0] != 0)
- {
- if (check_saved_game())
- {
- textcolor( BROWN );
- cprintf( EOL "Welcome back, " );
- textcolor( YELLOW );
- cprintf( "%s!", you.your_name );
- textcolor( LIGHTGREY );
+ case IDESC_SCROLLS: // scrolls
+ case IDESC_SCROLLS_II:
+ you.item_description[i][j] = random2(151);
+ break;
- save_player_name();
- return (false);
+ case IDESC_RINGS: // rings
+ you.item_description[i][j] = random2( 13 * 13 );
+ if (coinflip())
+ you.item_description[i][j] %= 13;
+ break;
+ }
+
+ bool is_ok = true;
+
+ // test whether we've used this description before
+ // don't have p < j because some are preassigned
+ for (int p = 0; p < you.item_description.height(); p++)
+ {
+ if ( p == j )
+ continue;
+
+ if (you.item_description[i][p]==you.item_description[i][j])
+ {
+ is_ok = false;
+ break;
+ }
+ }
+ if ( is_ok )
+ break;
+ }
}
}
+}
- reset_newgame_options();
- if (Options.random_pick)
+static void give_starting_food()
+{
+ // the undead start with no food
+ if (you.is_undead != US_ALIVE)
+ return;
+
+ item_def item;
+ if ( you.species == SP_SPRIGGAN )
{
- pick_random_species_and_class();
- ng_random = true;
+ item.base_type = OBJ_POTIONS;
+ item.sub_type = POT_PORRIDGE;
}
else
{
- while (choose_race() && !choose_class());
+ item.base_type = OBJ_FOOD;
+ if (you.species == SP_HILL_ORC || you.species == SP_KOBOLD ||
+ you.species == SP_OGRE || you.species == SP_TROLL)
+ item.sub_type = FOOD_MEAT_RATION;
+ else
+ item.sub_type = FOOD_BREAD_RATION;
}
+ item.quantity = 1;
- strcpy( you.class_name, get_class_name( you.char_class ) );
+ const int slot = find_free_slot(item);
+ you.inv[slot] = item; // will ASSERT if couldn't find free slot
+}
- // new: pick name _after_ race and class choices
- if (you.your_name[0] == 0)
+static void mark_starting_books()
+{
+ for (int i = 0; i < ENDOFPACK; i++)
{
- clrscr();
-
- char spec_buff[80];
- strncpy(spec_buff,
- species_name(you.species, you.experience_level), 80);
-
- snprintf( info, INFO_SIZE, "You are a%s %s %s." EOL,
- (is_vowel( spec_buff[0] )) ? "n" : "", spec_buff,
- you.class_name );
+ if (is_valid_item(you.inv[i]) && you.inv[i].base_type == OBJ_BOOKS)
+ {
+ const int subtype = you.inv[i].sub_type;
- cprintf( info );
+ you.had_book[subtype] = true;
- enter_player_name(false);
-
- if (check_saved_game())
- {
- cprintf(EOL "Do you really want to overwrite your old game?");
- char c = getch();
- if (!(c == 'Y' || c == 'y'))
+ // one for all, all for one
+ if (subtype == BOOK_MINOR_MAGIC_I ||
+ subtype == BOOK_MINOR_MAGIC_II ||
+ subtype == BOOK_MINOR_MAGIC_III)
{
- textcolor( BROWN );
- cprintf(EOL EOL "Welcome back, ");
- textcolor( YELLOW );
- cprintf("%s!", you.your_name);
- textcolor( LIGHTGREY );
+ you.had_book[BOOK_MINOR_MAGIC_I] = true;
+ you.had_book[BOOK_MINOR_MAGIC_II] = true;
+ you.had_book[BOOK_MINOR_MAGIC_III] = true;
+ }
- return (false);
+ if (subtype == BOOK_CONJURATIONS_I ||
+ subtype == BOOK_CONJURATIONS_II)
+ {
+ you.had_book[BOOK_CONJURATIONS_I] = true;
+ you.had_book[BOOK_CONJURATIONS_II] = true;
}
}
}
+}
+static void racialise_starting_equipment()
+{
+ for (int i = 0; i < ENDOFPACK; i++)
+ {
+ if (is_valid_item(you.inv[i]))
+ {
+ // don't change object type modifier unless it starts plain
+ if ((you.inv[i].base_type == OBJ_ARMOUR ||
+ you.inv[i].base_type == OBJ_WEAPONS ||
+ you.inv[i].base_type == OBJ_MISSILES)
+ && get_equip_race(you.inv[i]) == ISFLAG_NO_RACE )
+ {
+ // now add appropriate species type mod
+ switch (you.species)
+ {
+ case SP_ELF:
+ case SP_HIGH_ELF:
+ case SP_GREY_ELF:
+ case SP_DEEP_ELF:
+ case SP_SLUDGE_ELF:
+ set_equip_race( you.inv[i], ISFLAG_ELVEN );
+ break;
-// ************ round-out character statistics and such ************
+ case SP_HILL_DWARF:
+ case SP_MOUNTAIN_DWARF:
+ set_equip_race( you.inv[i], ISFLAG_DWARVEN );
+ break;
- species_stat_init( you.species ); // must be down here {dlb}
+ case SP_HILL_ORC:
+ set_equip_race( you.inv[i], ISFLAG_ORCISH );
+ break;
+ }
+ }
+ }
+ }
+}
- you.is_undead = ((you.species == SP_MUMMY) ? US_UNDEAD :
- (you.species == SP_GHOUL) ? US_HUNGRY_DEAD : US_ALIVE);
+// Characters are actually granted skill points, not skill levels.
+// Here we take racial aptitudes into account in determining final
+// skill levels.
+static void reassess_starting_skills()
+{
+ for (int i = 0; i < NUM_SKILLS; i++)
+ {
+ if (!you.skills[i])
+ continue;
- // before we get into the inventory init, set light radius based
- // on species vision. currently, all species see out to 8 squares.
- you.normal_vision = 8;
- you.current_vision = 8;
+ // Grant the amount of skill points required for a human
+ const int points = skill_exp_needed( you.skills[i] + 1 );
+ you.skill_points[i] = (points * species_skills(i, SP_HUMAN))/100 + 1;
- jobs_stat_init( you.char_class );
- give_last_paycheck( you.char_class );
+ // Find out what level that earns this character.
+ const int sp_diff = species_skills( i, you.species );
+ you.skills[i] = 0;
- // randomly boost stats a number of times based on species
- // - should be a function {dlb}
- unsigned char points_left = (you.species == SP_DEMIGOD
- || you.species == SP_DEMONSPAWN) ? 15 : 8;
+ for (int lvl = 1; lvl <= 8; lvl++)
+ {
+ if (you.skill_points[i] > (skill_exp_needed(lvl+1) * sp_diff)/100)
+ you.skills[i] = lvl;
+ else
+ break;
+ }
+ }
+}
+// randomly boost stats a number of times
+static void assign_remaining_stats( int points_left )
+{
// first spend points to get us to the minimum allowed value -- bwr
if (you.strength < MIN_START_STAT)
{
@@ -508,6 +588,7 @@ bool new_game(void)
// now randomly assign the remaining points --bwr
while (points_left > 0)
{
+ // stats that are already high will be chosen half as often
switch (random2( NUM_STATS ))
{
case STAT_STRENGTH:
@@ -534,11 +615,10 @@ bool new_game(void)
points_left--;
}
+}
- // this function depends on stats being finalized
- give_items_skills();
-
- // then: adjust hp_max by species {dlb}
+static void give_species_bonus_hp()
+{
if (player_genus(GENPC_DRACONIAN) || player_genus(GENPC_DWARVEN))
inc_max_hp(1);
else
@@ -584,8 +664,11 @@ bool new_game(void)
break;
}
}
+}
- // then: adjust max_magic_points by species {dlb}
+static void give_species_bonus_mp()
+{
+ // adjust max_magic_points by species {dlb}
switch (you.species)
{
case SP_SPRIGGAN:
@@ -598,196 +681,147 @@ bool new_game(void)
default:
break;
}
+}
- // these need to be set above using functions!!! {dlb}
- you.max_dex = you.dex;
- you.max_strength = you.strength;
- you.max_intel = you.intel;
+bool new_game(void)
+{
+ //jmf: NEW ASSERTS: we ought to do a *lot* of these
+ ASSERT(NUM_SPELLS < SPELL_NO_SPELL);
+ ASSERT(NUM_JOBS < JOB_UNKNOWN);
+ ASSERT(NUM_ATTRIBUTES >= 30);
+
+ init_player();
- if (!you.is_undead)
+ if (!Options.player_name.empty())
{
- for (i = 0; i < ENDOFPACK; i++)
- {
- if (!you.inv[i].quantity)
- {
- you.inv[i].quantity = 1;
- if (you.species == SP_SPRIGGAN)
- {
- you.inv[i].base_type = OBJ_POTIONS;
- you.inv[i].sub_type = POT_PORRIDGE;
- }
- else
- {
- you.inv[i].base_type = OBJ_FOOD;
- you.inv[i].sub_type = FOOD_BREAD_RATION;
- }
+ strncpy(you.your_name, Options.player_name.c_str(), kNameLen);
+ you.your_name[kNameLen - 1] = 0;
+ }
- if (you.species == SP_HILL_ORC || you.species == SP_KOBOLD
- || you.species == SP_OGRE || you.species == SP_TROLL)
- {
- you.inv[i].sub_type = FOOD_MEAT_RATION;
- }
+ textcolor(LIGHTGREY);
- break;
- }
- }
+ // copy name into you.your_name if set from environment --
+ // note that you.your_name could already be set from init.txt
+ // this, clearly, will overwrite such information {dlb}
+ if (SysEnv.crawl_name)
+ {
+ strncpy( you.your_name, SysEnv.crawl_name, kNameLen );
+ you.your_name[ kNameLen - 1 ] = 0;
}
- for (i = 0; i < ENDOFPACK; i++)
+ openingScreen();
+ enter_player_name(true);
+
+ if (you.your_name[0] != 0)
{
- if (you.inv[i].quantity)
+ if (check_saved_game())
{
- if (you.inv[i].base_type == OBJ_BOOKS)
- {
- you.had_book[you.inv[i].sub_type] = 1;
- if (you.inv[i].sub_type == BOOK_MINOR_MAGIC_I
- || you.inv[i].sub_type == BOOK_MINOR_MAGIC_II
- || you.inv[i].sub_type == BOOK_MINOR_MAGIC_III)
- {
- you.had_book[BOOK_MINOR_MAGIC_I] = 1;
- you.had_book[BOOK_MINOR_MAGIC_II] = 1;
- you.had_book[BOOK_MINOR_MAGIC_III] = 1;
- }
- if (you.inv[i].sub_type == BOOK_CONJURATIONS_I
- || you.inv[i].sub_type == BOOK_CONJURATIONS_II)
- {
- you.had_book[BOOK_CONJURATIONS_I] = 1;
- you.had_book[BOOK_CONJURATIONS_II] = 1;
- }
- }
-
- // don't change object type modifier unless it starts plain
- if (you.inv[i].base_type <= OBJ_ARMOUR
- && get_equip_race(you.inv[i]) == 0 ) // == DARM_PLAIN
- {
- // now add appropriate species type mod:
- switch (you.species)
- {
- case SP_ELF:
- case SP_HIGH_ELF:
- case SP_GREY_ELF:
- case SP_DEEP_ELF:
- case SP_SLUDGE_ELF:
- set_equip_race( you.inv[i], ISFLAG_ELVEN );
- break;
-
- case SP_HILL_DWARF:
- case SP_MOUNTAIN_DWARF:
- set_equip_race( you.inv[i], ISFLAG_DWARVEN );
- break;
+ textcolor( BROWN );
+ cprintf( EOL "Welcome back, " );
+ textcolor( YELLOW );
+ cprintf( "%s!", you.your_name );
+ textcolor( LIGHTGREY );
- case SP_HILL_ORC:
- set_equip_race( you.inv[i], ISFLAG_ORCISH );
- break;
- }
- }
+ save_player_name();
+ return (false);
}
}
- // must remember to check for already existing colours/combinations
- for (i = 0; i < 4; i++)
+ reset_newgame_options();
+ if (Options.random_pick)
{
- for (j = 0; j < 50; j++)
- {
- you.item_description[i][j] = 255;
- }
+ pick_random_species_and_class();
+ ng_random = true;
+ }
+ else
+ {
+ while (choose_race() && !choose_class());
}
- you.item_description[IDESC_POTIONS][POT_PORRIDGE] =
- PDESCQ(PDQ_GLUGGY, PDC_WHITE);
-
- you.item_description[IDESC_POTIONS][POT_WATER] =
- PDESCS(PDC_CLEAR);
-
- int passout;
+ strcpy( you.class_name, get_class_name( you.char_class ) );
- for (i = 0; i < 4; i++)
+ // new: pick name _after_ race and class choices
+ if (you.your_name[0] == 0)
{
- for (j = 0; j < 50; j++)
- {
- if (you.item_description[i][j] != 255)
- continue;
+ clrscr();
- do
- {
- passout = 1;
+ char spec_buff[80];
+ strncpy(spec_buff,
+ species_name(you.species, you.experience_level), 80);
- switch (i)
- {
- case IDESC_WANDS: // wands
- you.item_description[i][j] = random2( 16 * 12 );
- if (coinflip())
- you.item_description[i][j] %= 12;
- break;
+ snprintf( info, INFO_SIZE, "You are a%s %s %s." EOL,
+ (is_vowel( spec_buff[0] )) ? "n" : "", spec_buff,
+ you.class_name );
- case IDESC_POTIONS: // potions
- you.item_description[i][j] = random_potion_description();
- break;
+ cprintf( info );
- case IDESC_SCROLLS: // scrolls
- you.item_description[i][j] = random2(151);
- you.item_description[IDESC_SCROLLS_II][j] = random2(151);
- break;
+ enter_player_name(false);
- case IDESC_RINGS: // rings
- you.item_description[i][j] = random2( 13 * 13 );
- if (coinflip())
- you.item_description[i][j] %= 13;
- break;
- }
+ if (check_saved_game())
+ {
+ cprintf(EOL "Do you really want to overwrite your old game?");
+ char c = getch();
+ if (!(c == 'Y' || c == 'y'))
+ {
+ textcolor( BROWN );
+ cprintf(EOL EOL "Welcome back, ");
+ textcolor( YELLOW );
+ cprintf("%s!", you.your_name);
+ textcolor( LIGHTGREY );
- // don't have p < j because some are preassigned
- for (int p = 0; p < 50; p++)
- {
- if (you.item_description[i][p] == you.item_description[i][j]
- && j != p)
- {
- passout = 0;
- }
- }
+ return (false);
}
- while (passout == 0);
}
}
- for (i = 0; i < 50; i++)
- {
- if (!you.skills[i])
- continue;
- // Start with the amount of skill points required for a human...
- const int points = skill_exp_needed( you.skills[i] + 1 );
+// ************ round-out character statistics and such ************
- you.skill_points[i] = points + 1;
+ species_stat_init( you.species ); // must be down here {dlb}
- if (i == SK_SPELLCASTING)
- you.skill_points[i] = (points * 130) / 100 + 1;
- else if (i == SK_INVOCATIONS || i == SK_EVOCATIONS)
- you.skill_points[i] = (points * 75) / 100 + 1;
+ you.is_undead = ((you.species == SP_MUMMY) ? US_UNDEAD :
+ (you.species == SP_GHOUL) ? US_HUNGRY_DEAD : US_ALIVE);
- // ...and find out what level that earns this character.
- const int sp_diff = species_skills( i, you.species );
- you.skills[i] = 0;
+ // before we get into the inventory init, set light radius based
+ // on species vision. currently, all species see out to 8 squares.
+ you.normal_vision = 8;
+ you.current_vision = 8;
- for (int lvl = 1; lvl <= 8; lvl++)
- {
- if (you.skill_points[i] > (skill_exp_needed(lvl+1) * sp_diff) / 100)
- you.skills[i] = lvl;
- else
- break;
- }
- }
+ jobs_stat_init( you.char_class );
+ give_last_paycheck( you.char_class );
+
+ assign_remaining_stats((you.species == SP_DEMIGOD ||
+ you.species == SP_DEMONSPAWN) ? 15 : 8);
+
+ // this function depends on stats being finalized
+ give_items_skills();
+
+ give_species_bonus_hp();
+ give_species_bonus_mp();
+
+ // these need to be set above using functions!!! {dlb}
+ you.max_dex = you.dex;
+ you.max_strength = you.strength;
+ you.max_intel = you.intel;
+
+ give_starting_food();
+ mark_starting_books();
+ racialise_starting_equipment();
+
+ initialise_item_descriptions();
+ reassess_starting_skills();
calc_total_skill_points();
- for (i = 0; i < ENDOFPACK; i++)
+ for (int i = 0; i < ENDOFPACK; i++)
{
if (is_valid_item(you.inv[i]))
{
// identify all items in pack
set_ident_type( you.inv[i].base_type,
you.inv[i].sub_type, ID_KNOWN_TYPE );
-
+ // link properly
+ you.inv[i].link = i;
you.inv[i].slot = index_to_letter(you.inv[i].link);
item_colour( you.inv[i] ); // set correct special and colour
}
@@ -796,7 +830,7 @@ bool new_game(void)
// Brand items as original equipment.
origin_set_inventory(origin_set_startequip);
- // we calculate hp and mp here; all relevant factors should be
+ // we calculate hp and mp here; all relevant factors should be
// finalized by now (GDL)
calc_hp();
calc_mp();
@@ -809,13 +843,7 @@ bool new_game(void)
give_basic_knowledge(you.char_class);
// tmpfile purging removed in favour of marking
- for (int lvl = 0; lvl < MAX_LEVELS; lvl++)
- {
- for (int dng = 0; dng < NUM_BRANCHES; dng++)
- {
- tmp_file_pairs[lvl][dng] = false;
- }
- }
+ tmp_file_pairs.init(false);
give_basic_mutations(you.species);
initialise_branch_depths();