summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc1
-rw-r--r--crawl-ref/source/artefact.cc1
-rw-r--r--crawl-ref/source/command.cc1
-rw-r--r--crawl-ref/source/debug.cc2
-rw-r--r--crawl-ref/source/describe.cc2
-rw-r--r--crawl-ref/source/hiscores.cc2
-rw-r--r--crawl-ref/source/initfile.cc2
-rw-r--r--crawl-ref/source/jobs.cc192
-rw-r--r--crawl-ref/source/jobs.h13
-rw-r--r--crawl-ref/source/l_you.cc4
-rw-r--r--crawl-ref/source/makefile.obj2
-rw-r--r--crawl-ref/source/mon-util.cc1
-rw-r--r--crawl-ref/source/monspeak.cc2
-rw-r--r--crawl-ref/source/newgame.cc376
-rw-r--r--crawl-ref/source/newgame.h23
-rw-r--r--crawl-ref/source/output.cc2
-rw-r--r--crawl-ref/source/player.cc123
-rw-r--r--crawl-ref/source/player.h7
-rw-r--r--crawl-ref/source/skills2.cc1
-rw-r--r--crawl-ref/source/species.cc284
-rw-r--r--crawl-ref/source/species.h19
-rw-r--r--crawl-ref/source/spl-book.cc1
-rw-r--r--crawl-ref/source/tutorial.cc2
-rw-r--r--crawl-ref/source/view.cc1
24 files changed, 554 insertions, 510 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index f783222c72..507d840c85 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -39,6 +39,7 @@
#endif
#include "externs.h"
+#include "species.h"
#include "abl-show.h"
#include "abyss.h"
diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc
index 12fb20f74c..88a00138cd 100644
--- a/crawl-ref/source/artefact.cc
+++ b/crawl-ref/source/artefact.cc
@@ -15,6 +15,7 @@
#include <algorithm>
#include "externs.h"
+#include "species.h"
#include "database.h"
#include "describe.h"
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 674b1868da..d6ec426f20 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -14,6 +14,7 @@
#include <ctype.h>
#include "externs.h"
+#include "species.h"
#include "abl-show.h"
#include "branch.h"
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 4f0071eab8..d77c62f2e4 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -23,6 +23,7 @@
#endif
#include "externs.h"
+#include "species.h"
#include "artefact.h"
#include "beam.h"
@@ -60,6 +61,7 @@
#include "mon-util.h"
#include "mutation.h"
#include "newgame.h"
+#include "jobs.h"
#include "ouch.h"
#include "output.h"
#include "place.h"
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 2e6d8273d3..24588197ac 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -20,6 +20,7 @@
#endif
#include "externs.h"
+#include "species.h"
#include "abl-show.h"
#include "artefact.h"
@@ -42,6 +43,7 @@
#include "monstuff.h"
#include "mon-util.h"
#include "newgame.h"
+#include "jobs.h"
#include "player.h"
#include "religion.h"
#include "skills2.h"
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index e7b62dcd8b..5835416612 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -45,11 +45,13 @@
#include "message.h"
#include "mon-util.h"
#include "newgame.h"
+#include "jobs.h"
#include "ouch.h"
#include "place.h"
#include "player.h"
#include "religion.h"
#include "shopping.h"
+#include "species.h"
#include "state.h"
#include "stuff.h"
#include "tags.h"
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 75879e062e..1ddbd0ed5b 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -32,8 +32,10 @@
#include "message.h"
#include "mon-util.h"
#include "newgame.h"
+#include "jobs.h"
#include "player.h"
#include "religion.h"
+#include "species.h"
#include "stash.h"
#include "state.h"
#include "stuff.h"
diff --git a/crawl-ref/source/jobs.cc b/crawl-ref/source/jobs.cc
new file mode 100644
index 0000000000..14e88c55bc
--- /dev/null
+++ b/crawl-ref/source/jobs.cc
@@ -0,0 +1,192 @@
+#include "AppHdr.h"
+
+#include "jobs.h"
+
+// Listed in two columns to match the selection screen output.
+// Take care to list all valid classes here, or they cannot be directly chosen.
+// The old and new lists are expected to have the same length.
+static job_type old_jobs_order[] = {
+ JOB_FIGHTER, JOB_WIZARD,
+ JOB_PRIEST, JOB_THIEF,
+ JOB_GLADIATOR, JOB_NECROMANCER,
+ JOB_PALADIN, JOB_ASSASSIN,
+ JOB_BERSERKER, JOB_HUNTER,
+ JOB_CONJURER, JOB_ENCHANTER,
+ JOB_FIRE_ELEMENTALIST, JOB_ICE_ELEMENTALIST,
+ JOB_SUMMONER, JOB_AIR_ELEMENTALIST,
+ JOB_EARTH_ELEMENTALIST, JOB_CRUSADER,
+ JOB_DEATH_KNIGHT, JOB_VENOM_MAGE,
+ JOB_CHAOS_KNIGHT, JOB_TRANSMUTER,
+ JOB_HEALER, JOB_REAVER,
+ JOB_STALKER, JOB_MONK,
+ JOB_WARPER, JOB_WANDERER,
+ JOB_ARTIFICER
+};
+
+// First plain fighters, then religious fighters, then spell-casting
+// fighters, then primary spell-casters, then stabbers and shooters. (MM)
+static job_type new_jobs_order[] = {
+ // fighters
+ JOB_FIGHTER, JOB_GLADIATOR,
+ JOB_MONK, JOB_BERSERKER,
+ // religious professions (incl. Berserker above)
+ JOB_PALADIN, JOB_PRIEST,
+ JOB_HEALER, JOB_CHAOS_KNIGHT,
+ JOB_DEATH_KNIGHT, JOB_CRUSADER,
+ // general and niche spellcasters (incl. Crusader above)
+ JOB_REAVER, JOB_WARPER,
+ JOB_WIZARD, JOB_CONJURER,
+ JOB_ENCHANTER, JOB_SUMMONER,
+ JOB_NECROMANCER, JOB_TRANSMUTER,
+ JOB_FIRE_ELEMENTALIST, JOB_ICE_ELEMENTALIST,
+ JOB_AIR_ELEMENTALIST, JOB_EARTH_ELEMENTALIST,
+ // poison specialists and stabbers
+ JOB_VENOM_MAGE, JOB_STALKER,
+ JOB_THIEF, JOB_ASSASSIN,
+ JOB_HUNTER, JOB_ARTIFICER,
+ JOB_WANDERER
+};
+
+job_type get_class(const int index)
+{
+ if (index < 0 || (unsigned int) index >= ARRAYSZ(old_jobs_order))
+ return (JOB_UNKNOWN);
+
+ return (Options.use_old_selection_order? old_jobs_order[index]
+ : new_jobs_order[index]);
+}
+
+static const char * Class_Abbrev_List[ NUM_JOBS ] =
+ { "Fi", "Wz", "Pr", "Th", "Gl", "Ne", "Pa", "As", "Be", "Hu",
+ "Cj", "En", "FE", "IE", "Su", "AE", "EE", "Cr", "DK", "VM",
+ "CK", "Tm", "He", "Re", "St", "Mo", "Wr", "Wn", "Ar" };
+
+static const char * Class_Name_List[ NUM_JOBS ] =
+ { "Fighter", "Wizard", "Priest", "Thief", "Gladiator", "Necromancer",
+ "Paladin", "Assassin", "Berserker", "Hunter", "Conjurer", "Enchanter",
+ "Fire Elementalist", "Ice Elementalist", "Summoner", "Air Elementalist",
+ "Earth Elementalist", "Crusader", "Death Knight", "Venom Mage",
+ "Chaos Knight", "Transmuter", "Healer", "Reaver", "Stalker",
+ "Monk", "Warper", "Wanderer", "Artificer" };
+
+int get_class_index_by_abbrev( const char *abbrev )
+{
+ COMPILE_CHECK(ARRAYSZ(Class_Abbrev_List) == NUM_JOBS, c1);
+
+ unsigned int job;
+ for (unsigned int i = 0; i < ARRAYSZ(old_jobs_order); i++)
+ {
+ job = (Options.use_old_selection_order ? old_jobs_order[i]
+ : new_jobs_order[i]);
+
+ if (tolower( abbrev[0] ) == tolower( Class_Abbrev_List[job][0] )
+ && tolower( abbrev[1] ) == tolower( Class_Abbrev_List[job][1] ))
+ {
+ return i;
+ }
+ }
+
+ return (-1);
+}
+
+const char *get_class_abbrev( int which_job )
+{
+ ASSERT( which_job < NUM_JOBS );
+
+ return (Class_Abbrev_List[ which_job ]);
+}
+
+int get_class_by_abbrev( const char *abbrev )
+{
+ int i;
+
+ for (i = 0; i < NUM_JOBS; i++)
+ {
+ if (tolower( abbrev[0] ) == tolower( Class_Abbrev_List[i][0] )
+ && tolower( abbrev[1] ) == tolower( Class_Abbrev_List[i][1] ))
+ {
+ break;
+ }
+ }
+
+ return ((i < NUM_JOBS) ? i : -1);
+}
+
+int get_class_index_by_name( const char *name )
+{
+ COMPILE_CHECK(ARRAYSZ(Class_Name_List) == NUM_JOBS, c1);
+
+ char *ptr;
+ char lowered_buff[80];
+ char lowered_class[80];
+
+ strncpy( lowered_buff, name, sizeof( lowered_buff ) );
+ strlwr( lowered_buff );
+
+ int cl = -1;
+ unsigned int job;
+ for (unsigned int i = 0; i < ARRAYSZ(old_jobs_order); i++)
+ {
+ job = (Options.use_old_selection_order ? old_jobs_order[i]
+ : new_jobs_order[i]);
+
+ strncpy( lowered_class, Class_Name_List[job], sizeof( lowered_class ) );
+ strlwr( lowered_class );
+
+ ptr = strstr( lowered_class, lowered_buff );
+ if (ptr != NULL)
+ {
+ cl = i;
+ if (ptr == lowered_class) // prefix takes preference
+ break;
+ }
+ }
+
+ return (cl);
+}
+
+const char *get_class_name( int which_job )
+{
+ ASSERT( which_job < NUM_JOBS );
+
+ return (Class_Name_List[ which_job ]);
+}
+
+int get_class_by_name( const char *name )
+{
+ int i;
+ int cl = -1;
+
+ char *ptr;
+ char lowered_buff[80];
+ char lowered_class[80];
+
+ strncpy( lowered_buff, name, sizeof( lowered_buff ) );
+ strlwr( lowered_buff );
+
+ for (i = 0; i < NUM_JOBS; i++)
+ {
+ strncpy( lowered_class, Class_Name_List[i], sizeof( lowered_class ) );
+ strlwr( lowered_class );
+
+ ptr = strstr( lowered_class, lowered_buff );
+ if (ptr != NULL)
+ {
+ cl = i;
+ if (ptr == lowered_class) // prefix takes preference
+ break;
+ }
+ }
+
+ return (cl);
+}
+
+int ng_num_classes()
+{
+ // The list musn't be longer than the number of actual classes.
+ COMPILE_CHECK(ARRAYSZ(old_jobs_order) <= NUM_JOBS, c1);
+ // Check whether the two lists have the same size.
+ COMPILE_CHECK(ARRAYSZ(old_jobs_order) == ARRAYSZ(new_jobs_order), c2);
+ return ARRAYSZ(old_jobs_order);
+}
+
diff --git a/crawl-ref/source/jobs.h b/crawl-ref/source/jobs.h
new file mode 100644
index 0000000000..f885418f65
--- /dev/null
+++ b/crawl-ref/source/jobs.h
@@ -0,0 +1,13 @@
+#ifndef JOBS_H
+#define JOBS_H
+
+int ng_num_classes();
+job_type get_class(const int index);
+int get_class_index_by_abbrev(const char *abbrev);
+const char *get_class_abbrev(int which_job);
+int get_class_by_abbrev(const char *abbrev);
+int get_class_index_by_name(const char *name);
+const char *get_class_name(int which_job);
+int get_class_by_name(const char *name);
+
+#endif
diff --git a/crawl-ref/source/l_you.cc b/crawl-ref/source/l_you.cc
index 8e481ef9dc..e21f9d641d 100644
--- a/crawl-ref/source/l_you.cc
+++ b/crawl-ref/source/l_you.cc
@@ -10,9 +10,9 @@
#include "initfile.h"
#include "los.h"
#include "mon-util.h"
-#include "newgame.h"
+#include "jobs.h"
#include "ouch.h"
-#include "player.h"
+#include "species.h"
#include "religion.h"
#include "skills2.h"
#include "spells3.h"
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index c6c84b1660..3b64e04299 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -86,6 +86,8 @@ mt19937ar.o \
mtransit.o \
mutation.o \
newgame.o \
+jobs.o \
+species.o \
notes.o \
ouch.o \
output.o \
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index d6abdcae50..8fd9a97ba2 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -21,6 +21,7 @@
#include <algorithm>
#include "externs.h"
+#include "species.h"
#include "artefact.h"
#include "beam.h"
diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc
index 8d11f4619e..56b725984c 100644
--- a/crawl-ref/source/monspeak.cc
+++ b/crawl-ref/source/monspeak.cc
@@ -25,7 +25,7 @@
#include "message.h"
#include "monstuff.h"
#include "mon-util.h"
-#include "newgame.h"
+#include "jobs.h"
#include "player.h"
#include "religion.h"
#include "state.h"
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index 56dadf1be4..ffcfb01e4f 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -7,6 +7,7 @@
#include "AppHdr.h"
#include "newgame.h"
+#include "jobs.h"
#include <stdlib.h>
#include <stdio.h>
@@ -27,6 +28,7 @@
#endif
#include "externs.h"
+#include "species.h"
#include "abl-show.h"
#include "artefact.h"
@@ -96,332 +98,6 @@ static int ng_book;
static int ng_wand;
static god_type ng_pr;
-// March 2008: change order of species and jobs on character selection
-// screen as suggested by Markus Maier. Summarizing comments below are
-// copied directly from Markus' SourceForge comments. (jpeg)
-//
-// These are listed in two columns to match the selection screen output.
-// Take care to list all valid species here, or they cannot be directly
-// chosen.
-//
-// The red draconian is later replaced by a random variant.
-// The old and new lists are expected to have the same length.
-static species_type old_species_order[] = {
- SP_HUMAN, SP_HIGH_ELF,
- SP_DEEP_ELF, SP_SLUDGE_ELF,
- SP_MOUNTAIN_DWARF, SP_HALFLING,
- SP_HILL_ORC, SP_KOBOLD,
- SP_MUMMY, SP_NAGA,
- SP_OGRE, SP_TROLL,
- SP_RED_DRACONIAN, SP_CENTAUR,
- SP_DEMIGOD, SP_SPRIGGAN,
- SP_MINOTAUR, SP_DEMONSPAWN,
- SP_GHOUL, SP_KENKU,
- SP_MERFOLK, SP_VAMPIRE,
- SP_DEEP_DWARF
-};
-
-// Fantasy staples and humanoid creatures come first, then diminutive and
-// stealthy creatures, then monstrous creatures, then planetouched and after
-// all living creatures finally the undead. (MM)
-static species_type new_species_order[] = {
- // comparatively human-like looks
- SP_HUMAN, SP_HIGH_ELF,
- SP_DEEP_ELF, SP_SLUDGE_ELF,
- SP_MOUNTAIN_DWARF, SP_DEEP_DWARF,
- SP_HILL_ORC, SP_MERFOLK,
- // small species
- SP_HALFLING, SP_KOBOLD,
- SP_SPRIGGAN,
- // significantly different body type from human
- SP_NAGA, SP_CENTAUR,
- SP_OGRE, SP_TROLL,
- SP_MINOTAUR, SP_KENKU,
- SP_RED_DRACONIAN,
- // celestial species
- SP_DEMIGOD, SP_DEMONSPAWN,
- // undead species
- SP_MUMMY, SP_GHOUL,
- SP_VAMPIRE
-};
-
-static species_type _random_draconian_player_species()
-{
- const int num_drac = SP_PALE_DRACONIAN - SP_RED_DRACONIAN + 1;
- return static_cast<species_type>(SP_RED_DRACONIAN + random2(num_drac));
-}
-
-static species_type _get_species(const int index)
-{
- if (index < 0 || (unsigned int) index >= ARRAYSZ(old_species_order))
- return (SP_UNKNOWN);
-
- return (Options.use_old_selection_order ? old_species_order[index]
- : new_species_order[index]);
-}
-
-// Listed in two columns to match the selection screen output.
-// Take care to list all valid classes here, or they cannot be directly chosen.
-// The old and new lists are expected to have the same length.
-static job_type old_jobs_order[] = {
- JOB_FIGHTER, JOB_WIZARD,
- JOB_PRIEST, JOB_THIEF,
- JOB_GLADIATOR, JOB_NECROMANCER,
- JOB_PALADIN, JOB_ASSASSIN,
- JOB_BERSERKER, JOB_HUNTER,
- JOB_CONJURER, JOB_ENCHANTER,
- JOB_FIRE_ELEMENTALIST, JOB_ICE_ELEMENTALIST,
- JOB_SUMMONER, JOB_AIR_ELEMENTALIST,
- JOB_EARTH_ELEMENTALIST, JOB_CRUSADER,
- JOB_DEATH_KNIGHT, JOB_VENOM_MAGE,
- JOB_CHAOS_KNIGHT, JOB_TRANSMUTER,
- JOB_HEALER, JOB_REAVER,
- JOB_STALKER, JOB_MONK,
- JOB_WARPER, JOB_WANDERER,
- JOB_ARTIFICER
-};
-
-// First plain fighters, then religious fighters, then spell-casting
-// fighters, then primary spell-casters, then stabbers and shooters. (MM)
-static job_type new_jobs_order[] = {
- // fighters
- JOB_FIGHTER, JOB_GLADIATOR,
- JOB_MONK, JOB_BERSERKER,
- // religious professions (incl. Berserker above)
- JOB_PALADIN, JOB_PRIEST,
- JOB_HEALER, JOB_CHAOS_KNIGHT,
- JOB_DEATH_KNIGHT, JOB_CRUSADER,
- // general and niche spellcasters (incl. Crusader above)
- JOB_REAVER, JOB_WARPER,
- JOB_WIZARD, JOB_CONJURER,
- JOB_ENCHANTER, JOB_SUMMONER,
- JOB_NECROMANCER, JOB_TRANSMUTER,
- JOB_FIRE_ELEMENTALIST, JOB_ICE_ELEMENTALIST,
- JOB_AIR_ELEMENTALIST, JOB_EARTH_ELEMENTALIST,
- // poison specialists and stabbers
- JOB_VENOM_MAGE, JOB_STALKER,
- JOB_THIEF, JOB_ASSASSIN,
- JOB_HUNTER, JOB_ARTIFICER,
- JOB_WANDERER
-};
-
-static job_type _get_class(const int index)
-{
- if (index < 0 || (unsigned int) index >= ARRAYSZ(old_jobs_order))
- return (JOB_UNKNOWN);
-
- return (Options.use_old_selection_order? old_jobs_order[index]
- : new_jobs_order[index]);
-}
-
-static const char * Species_Abbrev_List[ NUM_SPECIES ] =
- { "XX", "Hu", "HE", "DE", "SE", "MD", "Ha",
- "HO", "Ko", "Mu", "Na", "Og", "Tr",
- // the draconians
- "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr",
- "Ce", "DG", "Sp", "Mi", "DS", "Gh", "Ke", "Mf", "Vp", "DD",
- // placeholders
- "El", "HD", "OM", "GE", "Gn" };
-
-int get_species_index_by_abbrev( const char *abbrev )
-{
- COMPILE_CHECK(ARRAYSZ(Species_Abbrev_List) == NUM_SPECIES, c1);
-
- for (unsigned i = 0; i < ARRAYSZ(old_species_order); i++)
- {
- const int sp = (Options.use_old_selection_order ? old_species_order[i]
- : new_species_order[i]);
-
- if (tolower( abbrev[0] ) == tolower( Species_Abbrev_List[sp][0] )
- && tolower( abbrev[1] ) == tolower( Species_Abbrev_List[sp][1] ))
- {
- return (i);
- }
- }
-
- return (-1);
-}
-
-int get_species_index_by_name( const char *name )
-{
- unsigned int i;
- int sp = -1;
-
- std::string::size_type pos = std::string::npos;
- char lowered_buff[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- for (i = 0; i < ARRAYSZ(old_species_order); i++)
- {
- const species_type real_sp
- = (Options.use_old_selection_order ? old_species_order[i]
- : new_species_order[i]);
-
- const std::string lowered_species =
- lowercase_string(species_name(real_sp,1));
- pos = lowered_species.find( lowered_buff );
- if (pos != std::string::npos)
- {
- sp = i;
- if (pos == 0) // prefix takes preference
- break;
- }
- }
-
- return (sp);
-}
-
-const char *get_species_abbrev( int which_species )
-{
- ASSERT( which_species > 0 && which_species < NUM_SPECIES );
-
- return (Species_Abbrev_List[ which_species ]);
-}
-
-// Needed for debug.cc and hiscores.cc.
-int get_species_by_abbrev( const char *abbrev )
-{
- int i;
- COMPILE_CHECK(ARRAYSZ(Species_Abbrev_List) == NUM_SPECIES, c1);
- for (i = SP_HUMAN; i < NUM_SPECIES; i++)
- {
- if (tolower( abbrev[0] ) == tolower( Species_Abbrev_List[i][0] )
- && tolower( abbrev[1] ) == tolower( Species_Abbrev_List[i][1] ))
- {
- break;
- }
- }
-
- return ((i < NUM_SPECIES) ? i : -1);
-}
-
-static const char * Class_Abbrev_List[ NUM_JOBS ] =
- { "Fi", "Wz", "Pr", "Th", "Gl", "Ne", "Pa", "As", "Be", "Hu",
- "Cj", "En", "FE", "IE", "Su", "AE", "EE", "Cr", "DK", "VM",
- "CK", "Tm", "He", "Re", "St", "Mo", "Wr", "Wn", "Ar" };
-
-static const char * Class_Name_List[ NUM_JOBS ] =
- { "Fighter", "Wizard", "Priest", "Thief", "Gladiator", "Necromancer",
- "Paladin", "Assassin", "Berserker", "Hunter", "Conjurer", "Enchanter",
- "Fire Elementalist", "Ice Elementalist", "Summoner", "Air Elementalist",
- "Earth Elementalist", "Crusader", "Death Knight", "Venom Mage",
- "Chaos Knight", "Transmuter", "Healer", "Reaver", "Stalker",
- "Monk", "Warper", "Wanderer", "Artificer" };
-
-int get_class_index_by_abbrev( const char *abbrev )
-{
- COMPILE_CHECK(ARRAYSZ(Class_Abbrev_List) == NUM_JOBS, c1);
-
- unsigned int job;
- for (unsigned int i = 0; i < ARRAYSZ(old_jobs_order); i++)
- {
- job = (Options.use_old_selection_order ? old_jobs_order[i]
- : new_jobs_order[i]);
-
- if (tolower( abbrev[0] ) == tolower( Class_Abbrev_List[job][0] )
- && tolower( abbrev[1] ) == tolower( Class_Abbrev_List[job][1] ))
- {
- return i;
- }
- }
-
- return (-1);
-}
-
-const char *get_class_abbrev( int which_job )
-{
- ASSERT( which_job < NUM_JOBS );
-
- return (Class_Abbrev_List[ which_job ]);
-}
-
-int get_class_by_abbrev( const char *abbrev )
-{
- int i;
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- if (tolower( abbrev[0] ) == tolower( Class_Abbrev_List[i][0] )
- && tolower( abbrev[1] ) == tolower( Class_Abbrev_List[i][1] ))
- {
- break;
- }
- }
-
- return ((i < NUM_JOBS) ? i : -1);
-}
-
-int get_class_index_by_name( const char *name )
-{
- COMPILE_CHECK(ARRAYSZ(Class_Name_List) == NUM_JOBS, c1);
-
- char *ptr;
- char lowered_buff[80];
- char lowered_class[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- int cl = -1;
- unsigned int job;
- for (unsigned int i = 0; i < ARRAYSZ(old_jobs_order); i++)
- {
- job = (Options.use_old_selection_order ? old_jobs_order[i]
- : new_jobs_order[i]);
-
- strncpy( lowered_class, Class_Name_List[job], sizeof( lowered_class ) );
- strlwr( lowered_class );
-
- ptr = strstr( lowered_class, lowered_buff );
- if (ptr != NULL)
- {
- cl = i;
- if (ptr == lowered_class) // prefix takes preference
- break;
- }
- }
-
- return (cl);
-}
-
-const char *get_class_name( int which_job )
-{
- ASSERT( which_job < NUM_JOBS );
-
- return (Class_Name_List[ which_job ]);
-}
-
-int get_class_by_name( const char *name )
-{
- int i;
- int cl = -1;
-
- char *ptr;
- char lowered_buff[80];
- char lowered_class[80];
-
- strncpy( lowered_buff, name, sizeof( lowered_buff ) );
- strlwr( lowered_buff );
-
- for (i = 0; i < NUM_JOBS; i++)
- {
- strncpy( lowered_class, Class_Name_List[i], sizeof( lowered_class ) );
- strlwr( lowered_class );
-
- ptr = strstr( lowered_class, lowered_buff );
- if (ptr != NULL)
- {
- cl = i;
- if (ptr == lowered_class) // prefix takes preference
- break;
- }
- }
-
- return (cl);
-}
-
static void _reset_newgame_options(void)
{
ng_race = ng_cls = 0;
@@ -472,13 +148,13 @@ static bool _prev_startup_options_set(void)
static std::string _get_opt_race_name(char race)
{
- species_type prace = _get_species(letter_to_index(race));
+ species_type prace = get_species(letter_to_index(race));
return (prace == SP_UNKNOWN? "Random" : species_name(prace, 1));
}
static std::string _get_opt_class_name(char oclass)
{
- job_type pclass = _get_class(letter_to_index(oclass));
+ job_type pclass = get_class(letter_to_index(oclass));
return (pclass == JOB_UNKNOWN? "Random" : get_class_name(pclass));
}
@@ -600,7 +276,7 @@ static void _pick_random_species_and_class( bool unrestricted_only )
// Return draconian variety here.
if (species == SP_RED_DRACONIAN)
- you.species = _random_draconian_player_species();
+ you.species = random_draconian_player_species();
else
you.species = species;
@@ -1216,8 +892,8 @@ game_start:
{
if (Options.race != 0 && Options.cls != 0
&& Options.race != '*' && Options.cls != '*'
- && !_class_allowed(_get_species(letter_to_index(Options.race)),
- _get_class(letter_to_index(Options.cls))))
+ && !_class_allowed(get_species(letter_to_index(Options.race)),
+ get_class(letter_to_index(Options.cls))))
{
end(1, false,
"Incompatible species and job specified in options file.");
@@ -1228,7 +904,7 @@ game_start:
// Pick random draconian type.
if (you.species == SP_RED_DRACONIAN)
- you.species = _random_draconian_player_species();
+ you.species = random_draconian_player_species();
strcpy( you.class_name, get_class_name(you.char_class) );
@@ -4458,21 +4134,13 @@ bool choose_race()
if (Options.cls)
{
- you.char_class = _get_class(letter_to_index(Options.cls));
+ you.char_class = get_class(letter_to_index(Options.cls));
ng_cls = Options.cls;
}
if (Options.race != 0)
printed = true;
- // The list musn't be longer than the number of actual species.
- COMPILE_CHECK(ARRAYSZ(old_species_order) <= NUM_SPECIES, c1);
-
- // Check whether the two lists have the same size.
- COMPILE_CHECK(ARRAYSZ(old_species_order) == ARRAYSZ(new_species_order), c2);
-
- const int num_species = ARRAYSZ(old_species_order);
-
spec_query:
bool prevraceok = (Options.prev_race == '*');
if (!printed)
@@ -4521,9 +4189,9 @@ spec_query:
textcolor( LIGHTGREY );
int j = 0;
- for (int i = 0; i < num_species; ++i)
+ for (int i = 0; i < ng_num_species(); ++i)
{
- const species_type si = _get_species(i);
+ const species_type si = get_species(i);
if (!_is_species_valid_choice(si))
continue;
@@ -4680,18 +4348,18 @@ spec_query:
int index;
do
{
- index = random2(num_species);
+ index = random2(ng_num_species());
}
- while (!_is_species_valid_choice(_get_species(index), false)
+ while (!_is_species_valid_choice(get_species(index), false)
|| you.char_class != JOB_UNKNOWN
- && !_is_good_combination(_get_species(index), you.char_class,
+ && !_is_good_combination(get_species(index), you.char_class,
good_randrace));
keyn = index_to_letter(index);
}
if (keyn >= 'a' && keyn <= 'z' || keyn >= 'A' && keyn <= 'Z')
- you.species = _get_species(letter_to_index(keyn));
+ you.species = get_species(letter_to_index(keyn));
if (!_is_species_valid_choice( you.species ))
{
@@ -4732,14 +4400,6 @@ bool choose_class(void)
ng_cls = 0;
- // The list musn't be longer than the number of actual classes.
- COMPILE_CHECK(ARRAYSZ(old_jobs_order) <= NUM_JOBS, c1);
-
- // Check whether the two lists have the same size.
- COMPILE_CHECK(ARRAYSZ(old_jobs_order) == ARRAYSZ(new_jobs_order), c2);
-
- const int num_classes = ARRAYSZ(old_jobs_order);
-
job_query:
bool prevclassok = (Options.prev_cls == '*');
if (!printed)
@@ -4771,9 +4431,9 @@ job_query:
int j = 0;
job_type which_job;
- for (int i = 0; i < num_classes; i++)
+ for (int i = 0; i < ng_num_classes(); i++)
{
- which_job = _get_class(i);
+ which_job = get_class(i);
// Dim text for restricted classes.
// Thief and wanderer are general challenge classes in that there's
@@ -4951,7 +4611,7 @@ job_query:
ASSERT( chosen_job != JOB_UNKNOWN );
}
else if (keyn >= 'a' && keyn <= 'z' || keyn >= 'A' && keyn <= 'Z')
- chosen_job = _get_class(letter_to_index(keyn));
+ chosen_job = get_class(letter_to_index(keyn));
if (chosen_job == JOB_UNKNOWN)
{
diff --git a/crawl-ref/source/newgame.h b/crawl-ref/source/newgame.h
index 4dc9446073..bb3feb5dbd 100644
--- a/crawl-ref/source/newgame.h
+++ b/crawl-ref/source/newgame.h
@@ -8,6 +8,9 @@
#ifndef NEWGAME_H
#define NEWGAME_H
+
+#include "itemprop.h"
+
enum death_knight_type
{
DK_NO_SELECTION,
@@ -37,26 +40,6 @@ enum startup_wand_type
SWT_RANDOM
};
-/* ***********************************************************************
- * called from: initfile
- * *********************************************************************** */
-int get_species_index_by_abbrev(const char *abbrev);
-int get_species_index_by_name(const char *name);
-const char *get_species_abbrev(int which_species);
-
-int get_class_index_by_abbrev(const char *abbrev);
-int get_class_index_by_name(const char *name);
-const char *get_class_abbrev(int which_job);
-const char *get_class_name(int which_job);
-
-/* ***********************************************************************
- * called from: debug and hiscores
- * *********************************************************************** */
-int get_species_by_abbrev( const char *abbrev );
-int get_species_by_name( const char *name );
-int get_class_by_abbrev( const char *abbrev );
-int get_class_by_name( const char *name );
-
undead_state_type get_undead_state(const species_type sp);
/* ***********************************************************************
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index 8f3946d49c..938948e626 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -16,6 +16,7 @@
#endif
#include "externs.h"
+#include "species.h"
#include "abl-show.h"
#include "branch.h"
@@ -35,6 +36,7 @@
#include "monstuff.h"
#include "mon-util.h"
#include "newgame.h"
+#include "jobs.h"
#include "ouch.h"
#include "player.h"
#include "place.h"
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index d35ab135f9..377c3f5752 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -50,6 +50,7 @@
#include "religion.h"
#include "skills.h"
#include "skills2.h"
+#include "species.h"
#include "spells1.h"
#include "spells3.h"
#include "spells4.h"
@@ -4294,128 +4295,6 @@ void display_char_status()
#endif
}
-// Does a case-sensitive lookup of the species name supplied.
-int str_to_species(const std::string &species)
-{
- if (species.empty())
- return SP_HUMAN;
-
- // first look for full name (e.g. Green Draconian)
- for (int i = SP_HUMAN; i < NUM_SPECIES; ++i)
- {
- if (species == species_name(static_cast<species_type>(i), 10))
- return (i);
- }
-
- // nothing found, try again with plain name
- for (int i = SP_HUMAN; i < NUM_SPECIES; ++i)
- {
- if (species == species_name(static_cast<species_type>(i), 1))
- return (i);
- }
-
- return (SP_HUMAN);
-}
-
-std::string species_name(species_type speci, int level, bool genus, bool adj)
-// defaults: false false
-{
- std::string res;
-
- if (player_genus( GENPC_DRACONIAN, speci ))
- {
- if (adj || genus) // adj doesn't care about exact species
- res = "Draconian";
- else
- {
- if (level < 7)
- res = "Draconian";
- else
- {
- switch (speci)
- {
- case SP_RED_DRACONIAN: res = "Red Draconian"; break;
- case SP_WHITE_DRACONIAN: res = "White Draconian"; break;
- case SP_GREEN_DRACONIAN: res = "Green Draconian"; break;
- case SP_YELLOW_DRACONIAN: res = "Yellow Draconian"; break;
- case SP_GREY_DRACONIAN: res = "Grey Draconian"; break;
- case SP_BLACK_DRACONIAN: res = "Black Draconian"; break;
- case SP_PURPLE_DRACONIAN: res = "Purple Draconian"; break;
- case SP_MOTTLED_DRACONIAN: res = "Mottled Draconian"; break;
- case SP_PALE_DRACONIAN: res = "Pale Draconian"; break;
-
- case SP_BASE_DRACONIAN:
- default:
- res = "Draconian";
- break;
- }
- }
- }
- }
- else if (player_genus( GENPC_ELVEN, speci ))
- {
- if (adj) // doesn't care about species/genus
- res = "Elven";
- else if (genus)
- res = "Elf";
- else
- {
- switch (speci)
- {
- case SP_HIGH_ELF: res = "High Elf"; break;
- case SP_DEEP_ELF: res = "Deep Elf"; break;
- case SP_SLUDGE_ELF: res = "Sludge Elf"; break;
- default: res = "Elf"; break;
- }
- }
- }
- else if (player_genus(GENPC_DWARVEN, speci))
- {
- if (adj) // doesn't care about species/genus
- res = "Dwarven";
- else if (genus)
- res = "Dwarf";
- else
- {
- switch (speci)
- {
- case SP_MOUNTAIN_DWARF: res = "Mountain Dwarf"; break;
- case SP_DEEP_DWARF: res = "Deep Dwarf"; break;
- default: res = "Dwarf"; break;
- }
- }
- }
- else
- {
- switch (speci)
- {
- case SP_HUMAN: res = "Human"; break;
- case SP_HALFLING: res = "Halfling"; break;
- case SP_KOBOLD: res = "Kobold"; break;
- case SP_MUMMY: res = "Mummy"; break;
- case SP_NAGA: res = "Naga"; break;
- case SP_CENTAUR: res = "Centaur"; break;
- case SP_SPRIGGAN: res = "Spriggan"; break;
- case SP_MINOTAUR: res = "Minotaur"; break;
- case SP_KENKU: res = "Kenku"; break;
-
- case SP_HILL_ORC:
- res = (adj ? "Orcish" : genus ? "Orc" : "Hill Orc");
- break;
-
- case SP_OGRE: res = (adj ? "Ogreish" : "Ogre"); break;
- case SP_TROLL: res = (adj ? "Trollish" : "Troll"); break;
- case SP_DEMIGOD: res = (adj ? "Divine" : "Demigod"); break;
- case SP_DEMONSPAWN: res = (adj ? "Demonic" : "Demonspawn"); break;
- case SP_GHOUL: res = (adj ? "Ghoulish" : "Ghoul"); break;
- case SP_MERFOLK: res = (adj ? "Merfolkian" : "Merfolk"); break;
- case SP_VAMPIRE: res = (adj ? "Vampiric" : "Vampire"); break;
- default: res = (adj ? "Yakish" : "Yak"); break;
- }
- }
- return res;
-}
-
bool player_item_conserve(bool calc_unid)
{
return (player_equip(EQ_AMULET, AMU_CONSERVATION, calc_unid)
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 2101cea229..d44e5dbfe7 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -558,13 +558,6 @@ bool wearing_amulet(jewellery_type which_am, bool calc_unid = true);
/* ***********************************************************************
- * called from: acr - chardump - describe - newgame - view
- * *********************************************************************** */
-std::string species_name( species_type speci, int level, bool genus = false,
- bool adj = false );
-int str_to_species(const std::string &species);
-
-/* ***********************************************************************
* called from: beam
* *********************************************************************** */
bool you_resist_magic(int power);
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index 6b34fc6e76..f701458b28 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -28,6 +28,7 @@
#include "itemprop.h"
#include "menu.h"
#include "player.h"
+#include "species.h"
#include "stuff.h"
#include "tutorial.h"
diff --git a/crawl-ref/source/species.cc b/crawl-ref/source/species.cc
new file mode 100644
index 0000000000..d55f871851
--- /dev/null
+++ b/crawl-ref/source/species.cc
@@ -0,0 +1,284 @@
+#include "AppHdr.h"
+
+#include "species.h"
+
+#include "stuff.h"
+
+// March 2008: change order of species and jobs on character selection
+// screen as suggested by Markus Maier. Summarizing comments below are
+// copied directly from Markus' SourceForge comments. (jpeg)
+//
+// These are listed in two columns to match the selection screen output.
+// Take care to list all valid species here, or they cannot be directly
+// chosen.
+//
+// The red draconian is later replaced by a random variant.
+// The old and new lists are expected to have the same length.
+static species_type old_species_order[] = {
+ SP_HUMAN, SP_HIGH_ELF,
+ SP_DEEP_ELF, SP_SLUDGE_ELF,
+ SP_MOUNTAIN_DWARF, SP_HALFLING,
+ SP_HILL_ORC, SP_KOBOLD,
+ SP_MUMMY, SP_NAGA,
+ SP_OGRE, SP_TROLL,
+ SP_RED_DRACONIAN, SP_CENTAUR,
+ SP_DEMIGOD, SP_SPRIGGAN,
+ SP_MINOTAUR, SP_DEMONSPAWN,
+ SP_GHOUL, SP_KENKU,
+ SP_MERFOLK, SP_VAMPIRE,
+ SP_DEEP_DWARF
+};
+
+// Fantasy staples and humanoid creatures come first, then diminutive and
+// stealthy creatures, then monstrous creatures, then planetouched and after
+// all living creatures finally the undead. (MM)
+static species_type new_species_order[] = {
+ // comparatively human-like looks
+ SP_HUMAN, SP_HIGH_ELF,
+ SP_DEEP_ELF, SP_SLUDGE_ELF,
+ SP_MOUNTAIN_DWARF, SP_DEEP_DWARF,
+ SP_HILL_ORC, SP_MERFOLK,
+ // small species
+ SP_HALFLING, SP_KOBOLD,
+ SP_SPRIGGAN,
+ // significantly different body type from human
+ SP_NAGA, SP_CENTAUR,
+ SP_OGRE, SP_TROLL,
+ SP_MINOTAUR, SP_KENKU,
+ SP_RED_DRACONIAN,
+ // celestial species
+ SP_DEMIGOD, SP_DEMONSPAWN,
+ // undead species
+ SP_MUMMY, SP_GHOUL,
+ SP_VAMPIRE
+};
+
+species_type random_draconian_player_species()
+{
+ const int num_drac = SP_PALE_DRACONIAN - SP_RED_DRACONIAN + 1;
+ return static_cast<species_type>(SP_RED_DRACONIAN + random2(num_drac));
+}
+
+species_type get_species(const int index)
+{
+ if (index < 0 || (unsigned int) index >= ARRAYSZ(old_species_order))
+ return (SP_UNKNOWN);
+
+ return (Options.use_old_selection_order ? old_species_order[index]
+ : new_species_order[index]);
+}
+
+static const char * Species_Abbrev_List[NUM_SPECIES] =
+ { "XX", "Hu", "HE", "DE", "SE", "MD", "Ha",
+ "HO", "Ko", "Mu", "Na", "Og", "Tr",
+ // the draconians
+ "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr", "Dr",
+ "Ce", "DG", "Sp", "Mi", "DS", "Gh", "Ke", "Mf", "Vp", "DD",
+ // placeholders
+ "El", "HD", "OM", "GE", "Gn" };
+
+int get_species_index_by_abbrev(const char *abbrev)
+{
+ COMPILE_CHECK(ARRAYSZ(Species_Abbrev_List) == NUM_SPECIES, c1);
+
+ for (unsigned i = 0; i < ARRAYSZ(old_species_order); i++)
+ {
+ const int sp = (Options.use_old_selection_order ? old_species_order[i]
+ : new_species_order[i]);
+
+ if (tolower( abbrev[0] ) == tolower( Species_Abbrev_List[sp][0] )
+ && tolower( abbrev[1] ) == tolower( Species_Abbrev_List[sp][1] ))
+ {
+ return (i);
+ }
+ }
+
+ return (-1);
+}
+
+int get_species_index_by_name( const char *name )
+{
+ unsigned int i;
+ int sp = -1;
+
+ std::string::size_type pos = std::string::npos;
+ char lowered_buff[80];
+
+ strncpy(lowered_buff, name, sizeof(lowered_buff));
+ strlwr(lowered_buff);
+
+ for (i = 0; i < ARRAYSZ(old_species_order); i++)
+ {
+ const species_type real_sp
+ = (Options.use_old_selection_order ? old_species_order[i]
+ : new_species_order[i]);
+
+ const std::string lowered_species =
+ lowercase_string(species_name(real_sp,1));
+ pos = lowered_species.find( lowered_buff );
+ if (pos != std::string::npos)
+ {
+ sp = i;
+ if (pos == 0) // prefix takes preference
+ break;
+ }
+ }
+
+ return (sp);
+}
+
+const char *get_species_abbrev( int which_species )
+{
+ ASSERT( which_species > 0 && which_species < NUM_SPECIES );
+
+ return (Species_Abbrev_List[ which_species ]);
+}
+
+// Needed for debug.cc and hiscores.cc.
+int get_species_by_abbrev( const char *abbrev )
+{
+ int i;
+ COMPILE_CHECK(ARRAYSZ(Species_Abbrev_List) == NUM_SPECIES, c1);
+ for (i = SP_HUMAN; i < NUM_SPECIES; i++)
+ {
+ if (tolower( abbrev[0] ) == tolower( Species_Abbrev_List[i][0] )
+ && tolower( abbrev[1] ) == tolower( Species_Abbrev_List[i][1] ))
+ {
+ break;
+ }
+ }
+
+ return ((i < NUM_SPECIES) ? i : -1);
+}
+
+int ng_num_species()
+{
+ // The list musn't be longer than the number of actual species.
+ COMPILE_CHECK(ARRAYSZ(old_species_order) <= NUM_SPECIES, c1);
+ // Check whether the two lists have the same size.
+ COMPILE_CHECK(ARRAYSZ(old_species_order) == ARRAYSZ(new_species_order), c2);
+ return (ARRAYSZ(old_species_order));
+}
+
+// Does a case-sensitive lookup of the species name supplied.
+int str_to_species(const std::string &species)
+{
+ if (species.empty())
+ return SP_HUMAN;
+
+ // first look for full name (e.g. Green Draconian)
+ for (int i = SP_HUMAN; i < NUM_SPECIES; ++i)
+ {
+ if (species == species_name(static_cast<species_type>(i), 10))
+ return (i);
+ }
+
+ // nothing found, try again with plain name
+ for (int i = SP_HUMAN; i < NUM_SPECIES; ++i)
+ {
+ if (species == species_name(static_cast<species_type>(i), 1))
+ return (i);
+ }
+
+ return (SP_HUMAN);
+}
+
+std::string species_name(species_type speci, int level, bool genus, bool adj)
+// defaults: false false
+{
+ std::string res;
+
+ if (player_genus( GENPC_DRACONIAN, speci ))
+ {
+ if (adj || genus) // adj doesn't care about exact species
+ res = "Draconian";
+ else
+ {
+ if (level < 7)
+ res = "Draconian";
+ else
+ {
+ switch (speci)
+ {
+ case SP_RED_DRACONIAN: res = "Red Draconian"; break;
+ case SP_WHITE_DRACONIAN: res = "White Draconian"; break;
+ case SP_GREEN_DRACONIAN: res = "Green Draconian"; break;
+ case SP_YELLOW_DRACONIAN: res = "Yellow Draconian"; break;
+ case SP_GREY_DRACONIAN: res = "Grey Draconian"; break;
+ case SP_BLACK_DRACONIAN: res = "Black Draconian"; break;
+ case SP_PURPLE_DRACONIAN: res = "Purple Draconian"; break;
+ case SP_MOTTLED_DRACONIAN: res = "Mottled Draconian"; break;
+ case SP_PALE_DRACONIAN: res = "Pale Draconian"; break;
+
+
+ case SP_BASE_DRACONIAN:
+ default:
+ res = "Draconian";
+ break;
+ }
+ }
+ }
+ }
+ else if (player_genus( GENPC_ELVEN, speci ))
+ {
+ if (adj) // doesn't care about species/genus
+ res = "Elven";
+ else if (genus)
+ res = "Elf";
+ else
+ {
+ switch (speci)
+ {
+ case SP_HIGH_ELF: res = "High Elf"; break;
+ case SP_DEEP_ELF: res = "Deep Elf"; break;
+ case SP_SLUDGE_ELF: res = "Sludge Elf"; break;
+ default: res = "Elf"; break;
+ }
+ }
+ }
+ else if (player_genus(GENPC_DWARVEN, speci))
+ {
+ if (adj) // doesn't care about species/genus
+ res = "Dwarven";
+ else if (genus)
+ res = "Dwarf";
+ else
+ {
+ switch (speci)
+ {
+ case SP_MOUNTAIN_DWARF: res = "Mountain Dwarf"; break;
+ case SP_DEEP_DWARF: res = "Deep Dwarf"; break;
+ default: res = "Dwarf"; break;
+ }
+ }
+ }
+ else
+ {
+ switch (speci)
+ {
+ case SP_HUMAN: res = "Human"; break;
+ case SP_HALFLING: res = "Halfling"; break;
+ case SP_KOBOLD: res = "Kobold"; break;
+ case SP_MUMMY: res = "Mummy"; break;
+ case SP_NAGA: res = "Naga"; break;
+ case SP_CENTAUR: res = "Centaur"; break;
+ case SP_SPRIGGAN: res = "Spriggan"; break;
+ case SP_MINOTAUR: res = "Minotaur"; break;
+ case SP_KENKU: res = "Kenku"; break;
+
+ case SP_HILL_ORC:
+ res = (adj ? "Orcish" : genus ? "Orc" : "Hill Orc");
+ break;
+
+ case SP_OGRE: res = (adj ? "Ogreish" : "Ogre"); break;
+ case SP_TROLL: res = (adj ? "Trollish" : "Troll"); break;
+ case SP_DEMIGOD: res = (adj ? "Divine" : "Demigod"); break;
+ case SP_DEMONSPAWN: res = (adj ? "Demonic" : "Demonspawn"); break;
+ case SP_GHOUL: res = (adj ? "Ghoulish" : "Ghoul"); break;
+ case SP_MERFOLK: res = (adj ? "Merfolkian" : "Merfolk"); break;
+ case SP_VAMPIRE: res = (adj ? "Vampiric" : "Vampire"); break;
+ default: res = (adj ? "Yakish" : "Yak"); break;
+ }
+ }
+ return res;
+}
diff --git a/crawl-ref/source/species.h b/crawl-ref/source/species.h
new file mode 100644
index 0000000000..03709311fa
--- /dev/null
+++ b/crawl-ref/source/species.h
@@ -0,0 +1,19 @@
+#ifndef SPECIES_H
+#define SPECIES_H
+
+// from newgame.cc
+species_type get_species(const int index);
+species_type random_draconian_player_species();
+int ng_num_species();
+int get_species_by_abbrev(const char *abbrev);
+const char *get_species_abbrev(int which_species);
+int get_species_index_by_abbrev(const char *abbrev);
+int get_species_index_by_name(const char *name);
+
+// from player.cc
+std::string species_name( species_type speci, int level, bool genus = false,
+ bool adj = false );
+int str_to_species(const std::string &species);
+
+#endif
+
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index ceef7af9dc..6facda5e46 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -20,6 +20,7 @@
#include "artefact.h"
#include "externs.h"
+#include "species.h"
#include "cio.h"
#include "database.h"
#include "debug.h"
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index 65019c5078..1948cf0c83 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -38,10 +38,12 @@
#include "monstuff.h"
#include "mutation.h"
#include "newgame.h"
+#include "jobs.h"
#include "player.h"
#include "religion.h"
#include "shopping.h"
#include "skills2.h"
+#include "species.h"
#include "spl-book.h"
#include "stuff.h"
#include "tags.h"
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 361d58bf5a..6f022f270d 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -44,6 +44,7 @@
#include "monstuff.h"
#include "mon-util.h"
#include "newgame.h"
+#include "jobs.h"
#include "notes.h"
#include "output.h"
#include "overmap.h"