summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/.gitignore3
-rw-r--r--crawl-ref/docs/aptitudes.txt147
-rw-r--r--crawl-ref/docs/template/apt-tmpl.txt51
-rw-r--r--crawl-ref/source/makefile34
-rwxr-xr-xcrawl-ref/source/util/gen-apt.pl246
5 files changed, 323 insertions, 158 deletions
diff --git a/crawl-ref/.gitignore b/crawl-ref/.gitignore
index 23910501a9..b207c2b3bb 100644
--- a/crawl-ref/.gitignore
+++ b/crawl-ref/.gitignore
@@ -23,6 +23,9 @@ DEADJOE
# Vim can generate extra swap files for the same file
*.sw[nop]
+# Generated documentation
+docs/aptitudes.txt
+
# Crawl generated junk
arena.result
saves
diff --git a/crawl-ref/docs/aptitudes.txt b/crawl-ref/docs/aptitudes.txt
deleted file mode 100644
index b87f63aa64..0000000000
--- a/crawl-ref/docs/aptitudes.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-TABLES OF APTITUDES
-
-The following three tables describe all aptitudes of the various species
-for the various skills. These are not necessary for winning in Crawl,
-neither explicit nor implicit. The qualitative information behind this
-sheet (i.e., which species is good at which tasks) can be obtained in
-two other, less sophisticated ways:
-- Read the species section in the manual about strengths and weaknesses.
-- Look at which combinations of species and job are recommended
- (lightgrey).
-
-If you consider figuring out such things yourself to be fun, stop
-reading now. Otherwise, just go ahead. The lower a value, the better the
-aptitude. 100 is the Human standard. Please note that many things affect
-how quickly a character will actually learn a skill. Thus, the numbers
-below are good enough for comparisons among species, but not necessarily
-among skills.
-
-The abbreviations used for the skills are:
-
-General skills, Experience Melee and Ranged Combat Spellcasting and Magic
--------------------------- ----------------------- ----------------------
-Arm - Armour Fgt - Fighting Spc - Spellcasting
-Ddg - Dodging SBl - Short Blades Coj - Conjurations
-Sth - Stealth LBl - Long Blades Enc - Enchantments
-Stb - Stabbing Axs - Axes Sum - Summonings
-Shd - Shields M&F - Maces & Flails Nec - Necromancy
-T&D - Traps & Doors Pla - Polearms Trl - Translocations
- Stv - Staves Trm - Transmutations
-Inv - Invocations U C - Unarmed Combat
-Evo - Evocations
- Thr - Throwing Fir - Fire Magic
- Slg - Slings Ice - Ice Magic
-Exp - Experience Bws - Bows Air - Air Magic
- Crb - Crossbows Ear - Earth Magic
- Poi - Poison Magic
-
-
- Arm Ddg Sth Stb Shd T&D Inv Evo Exp
----------------------------------------------------------------------
-Human 100 100 100 100 100 100 80 80 100
-High Elf 110 90 90 110 110 100 80 80 150
-Deep Elf 140 70 70 80 140 100 80 70 140
-Sludge Elf 140 70 80 100 130 100 80 80 120
-Mountain Dwarf 60 110 150 130 70 80 80 70 130
-Deep Dwarf 90 90 70 110 90 80 60 50 130
-Hill Orc 90 140 150 70 80 100 80 80 100
-Merfolk 160 60 90 70 100 120 80 80 120
-Halfling 150 70 60 70 90 100 80 70 100
-Kobold 140 70 60 70 130 100 80 60 100
-Spriggan 170 50 50 50 180 60 100 50 130
-Naga 150 150 40 100 140 100 80 80 120
-Centaur 180 170 200 170 180 150 80 100 140
-Ogre 150 120 150 150 120 150 80 120 110
-Troll 150 130 250 150 150 200 110 140 150
-Minotaur 80 80 130 100 80 120 100 130 140
-Kenku 90 90 100 80 100 100 120 80 130
-Draconian Red 200 120 120 100 100 100 80 80 130
- White 200 120 120 100 100 100 80 80 130
- Green 200 120 120 100 100 100 80 80 130
- Yellow 200 120 120 100 100 100 80 80 130
- Grey 200 120 120 100 100 100 80 80 130
- Black 200 120 120 100 100 100 80 80 130
- Purple 200 120 120 100 100 100 80 70 130
- Mottled 200 120 120 100 100 100 80 80 130
- Pale 200 120 120 100 100 100 80 70 130
-Demigod 110 110 110 110 110 110 80 80 160
-Demonspawn 110 110 110 110 110 110 60 80 140
-Mummy 140 140 140 140 140 140 110 110 150
-Ghoul 110 110 80 100 110 120 80 100 120
-Vampire 140 90 50 90 110 100 120 90 150
----------------------------------------------------------------------
- Arm Ddg Sth Stb Shd T&D Inv Evo Exp
-
-
- Fgt SBl LBl Axs M&F Pla Stv U C Thr Slg Bws Crb
----------------------------------------------------------------------
-Human 100 100 100 100 100 100 100 100 100 100 100 100
-High Elf 100 70 70 130 150 150 100 130 80 140 60 100
-Deep Elf 150 100 110 150 170 170 100 130 80 140 80 110
-Sludge Elf 80 110 110 130 140 140 100 80 70 100 100 100
-Mountain Dwarf 70 80 90 70 70 110 120 100 120 120 150 90
-Deep Dwarf 110 120 100 90 100 120 110 120 120 90 180 90
-Hill Orc 70 100 80 70 80 80 110 90 100 130 120 120
-Merfolk 80 70 90 140 150 50 130 90 100 150 140 140
-Halfling 120 60 100 120 150 160 130 140 60 50 70 90
-Kobold 80 60 140 110 100 150 110 100 60 70 90 80
-Spriggan 150 90 140 150 160 180 150 130 90 70 70 100
-Naga 100 100 100 100 100 100 120 100 120 120 120 120
-Centaur 100 120 110 110 110 110 110 100 60 80 60 90
-Ogre 70 200 180 180 90 110 120 110 80 180 180 180
-Troll 140 150 150 150 130 150 150 100 130 180 180 180
-Minotaur 70 70 70 70 70 70 70 80 90 90 90 90
-Kenku 100 80 80 80 80 80 80 80 90 100 80 80
-Draconian Red 90 100 100 100 100 100 100 100 120 120 120 120
- White 90 100 100 100 100 100 100 100 120 120 120 120
- Green 90 100 100 100 100 100 100 100 120 120 120 120
- Yellow 90 100 100 100 100 100 100 100 120 120 120 120
- Grey 90 100 100 100 100 100 100 100 120 120 120 120
- Black 90 100 100 100 100 100 100 100 120 120 120 120
- Purple 90 100 100 100 100 100 100 100 120 120 120 120
- Mottled 90 100 100 100 100 100 100 100 120 120 120 120
- Pale 90 100 100 100 100 100 100 100 120 120 120 120
-Demigod 110 110 110 110 110 110 110 110 110 110 110 110
-Demonspawn 100 110 110 110 110 110 110 110 110 110 110 110
-Mummy 100 140 140 140 140 140 140 140 140 140 140 140
-Ghoul 80 110 110 110 110 110 110 80 130 130 130 130
-Vampire 110 90 100 110 140 110 140 90 140 140 140 140
----------------------------------------------------------------------
- Fgt SBl LBl Axs M&F Pla Stv U C Thr Slg Bws Crb
-
-
- Spc Coj Enc Sum Nec Trl Trm Fir Ice Air Ear Poi
----------------------------------------------------------------------
-Human 130 100 100 100 100 100 100 100 100 100 100 100
-High Elf 90 90 70 110 130 90 90 100 100 70 130 130
-Deep Elf 70 80 50 80 70 80 80 90 90 80 100 80
-Sludge Elf 90 130 130 90 90 100 60 80 80 80 80 80
-Mountain Dwarf 210 120 150 150 160 150 120 70 130 150 70 130
-Deep Dwarf 160 120 120 110 80 90 120 110 110 170 60 130
-Hill Orc 200 100 120 100 100 150 160 100 100 150 100 110
-Merfolk 130 140 90 100 150 140 60 160 80 150 150 80
-Halfling 170 130 100 120 150 100 150 100 100 90 100 120
-Kobold 140 110 110 110 110 100 110 100 100 100 100 100
-Spriggan 80 160 50 150 120 50 60 140 140 120 120 100
-Naga 130 100 100 100 100 100 100 100 100 100 100 60
-Centaur 180 120 110 120 120 120 120 120 120 120 120 130
-Ogre 90 160 160 160 160 160 160 160 160 160 160 160
-Troll 260 160 200 160 150 160 160 160 160 200 120 160
-Minotaur 230 170 170 170 170 170 170 170 170 170 170 170
-Kenku 130 60 160 70 80 150 150 90 120 90 120 100
-Draconian Red 130 100 120 100 100 100 100 70 140 100 100 100
- White 130 100 120 100 100 100 100 140 70 100 100 100
- Green 130 100 120 100 100 100 100 100 100 100 100 70
- Yellow 130 100 120 100 100 100 100 100 100 100 100 100
- Grey 130 100 120 100 100 100 100 100 100 100 100 100
- Black 130 100 120 100 100 100 100 100 100 70 140 100
- Purple 90 100 90 100 100 100 100 100 100 100 100 100
- Mottled 130 100 120 100 100 100 100 80 100 100 100 100
- Pale 130 100 120 100 100 100 100 90 100 90 100 100
-Demigod 140 110 110 110 110 110 110 110 110 110 110 110
-Demonspawn 130 100 110 100 90 110 110 100 110 110 110 100
-Mummy 130 140 140 140 100 140 140 140 140 140 140 140
-Ghoul 160 130 130 120 100 120 120 150 90 150 90 100
-Vampire 130 160 90 100 90 140 90 140 100 100 120 120
----------------------------------------------------------------------
- Spc Coj Enc Sum Nec Trl Trm Fir Ice Air Ear Poi
diff --git a/crawl-ref/docs/template/apt-tmpl.txt b/crawl-ref/docs/template/apt-tmpl.txt
new file mode 100644
index 0000000000..39010715b9
--- /dev/null
+++ b/crawl-ref/docs/template/apt-tmpl.txt
@@ -0,0 +1,51 @@
+TABLES OF APTITUDES
+
+The following three tables describe all aptitudes of the various species
+for the various skills. These are not necessary for winning in Crawl,
+neither explicit nor implicit. The qualitative information behind this
+sheet (i.e., which species is good at which tasks) can be obtained in
+two other, less sophisticated ways:
+- Read the species section in the manual about strengths and weaknesses.
+- Look at which combinations of species and job are recommended
+ (lightgrey).
+
+If you consider figuring out such things yourself to be fun, stop
+reading now. Otherwise, just go ahead. The lower a value, the better the
+aptitude. 100 is the Human standard. Please note that many things affect
+how quickly a character will actually learn a skill. Thus, the numbers
+below are good enough for comparisons among species, but not necessarily
+among skills.
+
+The abbreviations used for the skills are:
+
+General skills, Experience Melee and Ranged Combat Spellcasting and Magic
+-------------------------- ----------------------- ----------------------
+Arm - Armour Fgt - Fighting Spc - Spellcasting
+Ddg - Dodging SBl - Short Blades Coj - Conjurations
+Sth - Stealth LBl - Long Blades Enc - Enchantments
+Stb - Stabbing Axs - Axes Sum - Summonings
+Shd - Shields M&F - Maces & Flails Nec - Necromancy
+T&D - Traps & Doors Pla - Polearms Trl - Translocations
+ Stv - Staves Trm - Transmutations
+Inv - Invocations UC - Unarmed Combat
+Evo - Evocations
+ Thr - Throwing Fir - Fire Magic
+ Slg - Slings Ice - Ice Magic
+Exp - Experience Bws - Bows Air - Air Magic
+ Crb - Crossbows Ear - Earth Magic
+ Poi - Poison Magic
+
+Please do not edit this table directly in docs/aptitudes.txt -- make
+changes to the template in docs/template/apt-tmpl.txt.
+
+
+ Arm Ddg Sth Stb Shd T&D Inv Evo Exp
+---------------------------------------------------------------------
+
+
+ Fgt SBl LBl Axs M&F Pla Stv UC Thr Slg Bws Crb
+---------------------------------------------------------------------
+
+
+ Spc Coj Enc Sum Nec Trl Trm Fir Ice Air Ear Poi
+---------------------------------------------------------------------
diff --git a/crawl-ref/source/makefile b/crawl-ref/source/makefile
index b926b2c659..bb360aec0e 100644
--- a/crawl-ref/source/makefile
+++ b/crawl-ref/source/makefile
@@ -706,16 +706,21 @@ endif
EXTRA_OBJECTS += version.o
LIBS += $(CONTRIB_LIBS) $(EXTRA_LIBS)
-GAME_DEPENDS := $(DESTTILEFILES) $(OBJECTS) $(EXTRA_OBJECTS) $(CONTRIB_LIBS)
-SRC_PKG_BASE := stone_soup
-SRC_VERSION := $(shell git describe --tags --long 2>/dev/null || cat util/release_ver)
-PKG_SRC_DIR := $(SRC_PKG_BASE)-$(SRC_VERSION)
-SRC_PKG_TAR := $(PKG_SRC_DIR).tar.bz2
-SRC_PKG_ZIP := $(PKG_SRC_DIR).zip
+
+DOC_BASE := ../docs
+DOC_TEMPLATES := $(DOC_BASE)/template
+GENERATE_DOCS := $(DOC_BASE)/aptitudes.txt
+
+GAME_DEPENDS := $(DESTTILEFILES) $(OBJECTS) $(EXTRA_OBJECTS) $(CONTRIB_LIBS)
+SRC_PKG_BASE := stone_soup
+SRC_VERSION := $(shell git describe --tags --long 2>/dev/null || cat util/release_ver)
+PKG_SRC_DIR := $(SRC_PKG_BASE)-$(SRC_VERSION)
+SRC_PKG_TAR := $(PKG_SRC_DIR).tar.bz2
+SRC_PKG_ZIP := $(PKG_SRC_DIR).zip
.PHONY: all test install clean clean-contrib distclean debug profile wizard package-source source
-all: $(GAME)
+all: $(GAME) $(GENERATE_DOCS)
test:
./$(GAME) -test > /dev/null
@@ -764,6 +769,13 @@ build.h: $(OBJECTS:.o=.cc)
version.cc: build.h compflag.h
##########################################################################
+# Documentation
+#
+$(DOC_BASE)/aptitudes.txt: $(DOC_TEMPLATES)/apt-tmpl.txt player.cc skills2.cc \
+ util/gen-apt.pl
+ $(QUIET_GEN)./util/gen-apt.pl $@ $^
+
+##########################################################################
# The level compiler
#
@@ -802,7 +814,7 @@ endif
##########################################################################
# The actual build targets
#
-install: $(GAME)
+install: all
ifeq ($(DESTDIR)$(prefix),)
@echo Neither "DESTDIR" nor "prefix" defined -- nowhere to install to, aborting.
@exit 1
@@ -861,9 +873,9 @@ distclean: clean clean-contrib clean-rltiles
$(GAME): $(GAME_DEPENDS)
$(QUIET_LINK)$(CXX) $(LDFLAGS) $(EXTRA_OBJECTS) $(OBJECTS) -o $(GAME) $(LIBS)
-debug: $(GAME)
-profile: $(GAME)
-wizard: $(GAME)
+debug: all
+profile: all
+wizard: all
# [ds] Note we don't use the standard CFLAGS here; that's intentional, most
# flex/bison combos I've tried don't produce code that passes the warnings
diff --git a/crawl-ref/source/util/gen-apt.pl b/crawl-ref/source/util/gen-apt.pl
new file mode 100755
index 0000000000..d19ec8a279
--- /dev/null
+++ b/crawl-ref/source/util/gen-apt.pl
@@ -0,0 +1,246 @@
+#! /usr/bin/env perl
+
+# Generates aptitude table from skills2.cc and the aptitude template file.
+# All species names are discovered from skills2.cc and all skill abbreviations
+# are discovered from the apt template file, so this script should be
+# reasonably insulated from skill and species changes.
+#
+
+use strict;
+use warnings;
+
+my ($target, $template, $expmodfile, $skillfile) = @ARGV;
+die "Usage: $0 <target> <template> player.cc skills2.cc\n"
+ unless ($expmodfile && $skillfile && $template && $target && -r $template
+ && -r $skillfile && -r $expmodfile);
+
+my %ABBR_SKILL;
+my %SKILL_ABBR;
+my %SPECIES_SKILLS;
+my @SPECIES;
+my %SEEN_SPECIES;
+
+main();
+
+sub main {
+ load_skill_abbreviations($template);
+ load_aptitudes($skillfile);
+ load_expmods($expmodfile);
+ create_aptitude_file($template, $target);
+}
+
+sub create_aptitude_file {
+ my ($template, $target) = @_;
+ open my $outf, '>', $target or die "Can't write $target: $!\n";
+ open my $inf, '<', $template or die "Can't read $template: $!\n";
+ my $foundmarkers;
+ my $lastline;
+ while (<$inf>) {
+ print $outf $_;
+ if (/^-{60,}/) {
+ $foundmarkers = 1;
+ print $outf aptitude_table($lastline);
+
+ # Repeat separator and headerline under the table.
+ print $outf $_;
+ print $outf $lastline;
+ }
+ $lastline = $_;
+ }
+ die "Could not find skill table sections in $template\n" unless $foundmarkers;
+}
+
+sub abbr_to_skill {
+ my $abbr = shift;
+ my $skill = $ABBR_SKILL{$abbr};
+ die "Could not find skill corresponding to abbreviation: $abbr\n"
+ unless $skill;
+ $skill
+}
+
+sub fix_draco_species {
+ my ($sp, $rseen) = @_;
+ if ($sp =~ /^(\w+) Draconian/) {
+ my $flavour = $1;
+ if (!$$rseen) {
+ $$rseen = length($sp);
+ $sp = "Draconian $flavour";
+ }
+ else {
+ $sp = sprintf("%*s", $$rseen, $flavour);
+ }
+ }
+ $sp
+}
+
+sub find_skill {
+ my ($species, $skill) = @_;
+ my $sk = $SPECIES_SKILLS{$species}{$skill};
+ die "Could not find skill $skill for $species\n" unless $sk;
+ $sk
+}
+
+sub split_species {
+ my $sp = shift;
+ if ($sp =~ /^(.*) (.*)$/) {
+ return ($2, $1);
+ }
+ return ($sp, $sp);
+}
+
+sub compare_species {
+ my ($a, $b) = @_;
+ return -1 if $a eq 'Human';
+ return 1 if $b eq 'Human';
+
+ my ($abase, $asub) = split_species($a);
+ my ($bbase, $bsub) = split_species($b);
+ my $basecmp = $abase cmp $bbase;
+ return $basecmp if $basecmp;
+ return $asub cmp $bsub;
+}
+
+sub sort_species {
+ sort { compare_species($a, $b) } @_
+}
+
+sub aptitude_table {
+ chomp(my $headers = shift);
+ my @skill_abbrevs = $headers =~ /(\S+)/g;
+
+ my $text = '';
+ my $seen_draconian_length;
+ for my $sp (sort_species(@SPECIES)) {
+ next if $sp eq 'Base Draconian';
+
+ my $line = '';
+ $line .= fix_draco_species($sp, \$seen_draconian_length);
+
+ for my $abbr (@skill_abbrevs) {
+ my $skill = find_skill($sp, abbr_to_skill($abbr));
+
+ my $pos = index($headers, " $abbr");
+ die "Could not find $abbr in $headers?\n" if $pos == -1;
+ $pos++;
+ if ($pos > length($line)) {
+ $line .= " " x ($pos - length($line));
+ }
+ $line .= sprintf("%*d", length($abbr), $skill);
+ }
+ $text .= "$line\n";
+ }
+ $text
+}
+
+sub skill_name {
+ my $text = shift;
+ $text =~ tr/a-zA-Z / /c;
+ $text =~ s/ +/ /g;
+ $text =~ s/s$//i;
+ propercase_string($text)
+}
+
+sub load_skill_abbreviations {
+ my $template = shift;
+ open my $inf, '<', $template or die "Can't read $template: $!\n";
+ my $in_abbr;
+ while (<$inf>) {
+ $in_abbr = 1 if /-{15,}/;
+ next unless $in_abbr;
+ while (/(\S+(?: \S+)*) {1,3}- {1,3}(\S+(?: \S+)*)/g) {
+ my $skill = $2;
+ my $abbr = $1;
+ $skill = skill_name($skill);
+ $SKILL_ABBR{$skill} = $abbr;
+ $ABBR_SKILL{$abbr} = $skill;
+ }
+ }
+ close $inf;
+
+ die "No skill names found in $template\n" unless %SKILL_ABBR;
+}
+
+sub propercase_string {
+ my $s = lc(shift);
+ $s =~ s/\b(\w)/\u$1/g;
+ $s
+}
+
+sub fix_underscores {
+ my $s = shift;
+ $s =~ tr/_/ /;
+ $s
+}
+
+sub load_aptitudes {
+ my $skillfile = shift;
+ open my $inf, '<', $skillfile or die "Can't read $skillfile: $!\n";
+ my $seen_skill_start;
+ my $species;
+
+ while (<$inf>) {
+ last if /\*{40,}/;
+ if (!$seen_skill_start) {
+ $seen_skill_start = 1 if /spec_skills\[/;
+ }
+ else {
+ if (m{//\s*SP_(\w+)\s*$}) {
+ $species = propercase_string(fix_underscores($1));
+ die "$skillfile:$.: Repeated skill def for $species.\n"
+ if $SEEN_SPECIES{$species};
+ $SEEN_SPECIES{$species} = 1;
+ push @SPECIES, $species;
+ }
+ if (m{//\s*SK_(\w+)\s*$} && /^\s*\d+/) {
+ m{//\s*SK_(\w+)\s*$};
+ my $skill = skill_name($1);
+ die "$skillfile:$.: Unknown skill: $skill\n"
+ unless $SKILL_ABBR{$skill};
+ die "$skillfile:$.: Repeated skill def $1 for $species.\n"
+ if $SPECIES_SKILLS{$species}{$skill};
+ ($SPECIES_SKILLS{$species}{$skill}) = /^\s*(\d+)/;
+ }
+ }
+ }
+ die "Could not find aptitudes for species in $skillfile\n"
+ unless %SPECIES_SKILLS;
+}
+
+sub species_for_genus {
+ my $genus = lc(shift);
+ $genus = 'dwarf' if $genus eq 'dwarven';
+ grep(index(lc($_), $genus) != -1, @SPECIES)
+}
+
+sub load_expmods {
+ my $expmodfile = shift;
+ open my $inf, '<', $expmodfile or die "Can't read $expmodfile: $!\n";
+
+ my $inexpmod;
+
+ my @species;
+ while (<$inf>) {
+ $inexpmod = 1 if /static.*species_exp_mod/;
+ next unless $inexpmod;
+
+ if (/GENPC_(\w+)/) {
+ push @species, species_for_genus($1);
+ }
+ if (/SP_(\w+)/) {
+ push @species, propercase_string(fix_underscores($1));
+ }
+
+ if (/return/ && /(\d+)/) {
+ my $exp = $1;
+ last if $exp eq '0';
+ die "$expmodfile:$.: No species associated with xp mod $1\n"
+ unless @species;
+ for my $sp (@species) {
+ $SPECIES_SKILLS{$sp}{Experience} = $1 * 10;
+ }
+ @species = ();
+ }
+ }
+ close $inf;
+ die "Could not find species exp mods in $expmodfile\n" unless $inexpmod;
+}